make reactivity system pluggable

This commit is contained in:
2026-05-04 23:07:32 -06:00
parent e72bb6d4c4
commit 4dca40ef61
11 changed files with 78 additions and 45 deletions
+26 -24
View File
@@ -3,11 +3,10 @@ use crate::AudioSettings;
use crate::Chat;
use crate::Command;
use crate::ConnectionState;
use crate::Reactivity;
use asynchronous_codec::FramedRead;
use asynchronous_codec::FramedWrite;
use color_eyre::eyre::{bail, Error};
use dioxus_signals::ReadableExt as _;
use dioxus_signals::WritableExt as _;
use futures::select;
use futures::AsyncRead;
use futures::AsyncWrite;
@@ -36,7 +35,10 @@ use crate::imp::{
Platform, PlatformInterface as _,
};
pub async fn network_entrypoint(mut event_rx: UnboundedReceiver<Command>, state: SharedState) {
pub async fn network_entrypoint<X: Reactivity>(
mut event_rx: UnboundedReceiver<Command>,
state: SharedState<X>,
) {
loop {
let Some(Command::Connect {
address,
@@ -47,16 +49,16 @@ pub async fn network_entrypoint(mut event_rx: UnboundedReceiver<Command>, state:
panic!("did not receive connect command")
};
*state.server.write_unchecked() = Default::default();
*state.status.write_unchecked() = ConnectionState::Connecting;
*X::write(&state.server) = Default::default();
*X::write(&state.status) = ConnectionState::Connecting;
if let Err(error) =
Platform::network_connect(address, username, &mut event_rx, &config, state.clone())
.await
{
error!("could not connect {:?}", error);
*state.status.write_unchecked() = ConnectionState::Failed(error.to_string());
*X::write(&state.status) = ConnectionState::Failed(error.to_string());
} else {
*state.status.write_unchecked() = ConnectionState::Disconnected;
*X::write(&state.status) = ConnectionState::Disconnected;
}
}
}
@@ -76,14 +78,14 @@ pub(crate) async fn sender_loop<W: AsyncWrite + Unpin + 'static>(
}
}
pub(crate) async fn network_loop<R: AsyncRead + Unpin + 'static>(
pub(crate) async fn network_loop<R: AsyncRead + Unpin + 'static, X: Reactivity>(
username: String,
state: SharedState,
state: SharedState<X>,
event_rx: &mut UnboundedReceiver<Command>,
mut outgoing: UnboundedSender<ControlPacket<Serverbound>>,
mut reader: FramedRead<R, ControlCodec<Serverbound, Clientbound>>,
) -> Result<(), Error> {
let audio_settings = state.audio.read().clone();
let audio_settings = X::read(&state.audio).clone();
// Get version packet
let version = match reader.next().await {
@@ -190,14 +192,14 @@ pub(crate) async fn network_loop<R: AsyncRead + Unpin + 'static>(
Ok(())
}
fn accept_command(
fn accept_command<X: Reactivity>(
command: Command,
send_chan: &mut UnboundedSender<ControlPacket<mumble_protocol::Serverbound>>,
audio: &mut AudioSystem,
state: &State,
state: &State<X>,
) -> Result<(), Error> {
use Command::*;
let Some(session) = state.server.read().session else {
let Some(session) = X::read(&state.server).session else {
bail!("no session id")
};
@@ -220,7 +222,7 @@ fn accept_command(
};
{
let mut server = state.server.write_unchecked();
let mut server = X::write(&state.server);
let Some(me) = server.session else {
bail!("not signed in with a session id")
};
@@ -261,7 +263,7 @@ fn accept_command(
};
{
let mut server = state.server.write_unchecked();
let mut server = X::write(&state.server);
let Some(me) = server.session else {
bail!("not signed in with a session id")
};
@@ -304,11 +306,11 @@ fn accept_command(
Ok(())
}
fn accept_packet(
fn accept_packet<X: Reactivity>(
msg: ControlPacket<mumble_protocol::Clientbound>,
audio_context: &mut AudioSystem,
player_map: &mut HashMap<u32, AudioPlayer>,
state: &State,
state: &State<X>,
) -> Result<(), Error> {
match msg {
ControlPacket::UDPTunnel(u) => {
@@ -345,15 +347,15 @@ fn accept_packet(
}
}
ControlPacket::ChannelState(u) => {
let mut server = state.server.write_unchecked();
let mut server = X::write(&state.server);
server.channels_state.update_from_channel_state(&u);
}
ControlPacket::ChannelRemove(u) => {
let mut server = state.server.write_unchecked();
let mut server = X::write(&state.server);
server.channels_state.update_from_channel_remove(&u);
}
ControlPacket::UserState(u) => {
let mut server = state.server.write_unchecked();
let mut server = X::write(&state.server);
let server = &mut *server;
let id = u.get_session();
@@ -397,7 +399,7 @@ fn accept_packet(
}
}
ControlPacket::UserRemove(u) => {
let mut server = state.server.write_unchecked();
let mut server = X::write(&state.server);
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) {
@@ -406,7 +408,7 @@ fn accept_packet(
}
}
ControlPacket::TextMessage(u) => {
let mut server = state.server.write_unchecked();
let mut server = X::write(&state.server);
if u.has_message() {
let text = u.get_message().to_string();
server.chat.push(Chat {
@@ -421,8 +423,8 @@ fn accept_packet(
}
}
ControlPacket::ServerSync(u) => {
*state.status.write_unchecked() = ConnectionState::Connected;
let mut server = state.server.write_unchecked();
*X::write(&state.status) = ConnectionState::Connected;
let mut server = X::write(&state.server);
if u.has_welcome_text() {
let text = u.get_welcome_text().to_string();
server.chat.push(Chat {