flnet-wasm 0.6.0

Network implementation for wasm
Documentation
use async_trait::async_trait;
use flmodules::broker::{Broker, Destination, Subsystem, SubsystemListener};
use flnet::web_rtc::messages::{
    PeerMessage, SetupError, WebRTCInput, WebRTCMessage, WebRTCOutput, WebRTCSpawner,
};

use crate::web_rtc_setup::WebRTCConnectionSetup;

pub struct WebRTCConnection {
    setup: WebRTCConnectionSetup,
}

impl WebRTCConnection {
    pub async fn new_box() -> Result<Broker<WebRTCMessage>, SetupError> {
        let broker = Broker::new();
        let rn = WebRTCConnection {
            setup: WebRTCConnectionSetup::new(broker.clone()).await?,
        };
        let rp_conn = rn.setup.rp_conn.clone();

        broker
            .clone()
            .add_subsystem(Subsystem::Handler(Box::new(rn)))
            .await?;
        WebRTCConnectionSetup::ice_start(&rp_conn, broker.clone());
        Ok(broker)
    }

    async fn setup(&mut self, pm: PeerMessage) -> Result<Option<PeerMessage>, SetupError> {
        Ok(match pm {
            PeerMessage::Init => Some(PeerMessage::Offer(self.setup.make_offer().await?)),
            PeerMessage::Offer(o) => Some(PeerMessage::Answer(self.setup.make_answer(o).await?)),
            PeerMessage::Answer(a) => {
                self.setup.use_answer(a).await?;
                None
            }
            PeerMessage::IceCandidate(ice) => {
                self.setup.ice_put(ice).await?;
                None
            }
        })
    }

    async fn msg_in(&mut self, msg: WebRTCInput) -> Result<Option<WebRTCMessage>, SetupError> {
        match msg {
            WebRTCInput::Text(s) => self.setup.send(s).await?,
            WebRTCInput::Setup(s) => {
                if let Some(msg) = self.setup(s).await? {
                    return Ok(Some(WebRTCMessage::Output(WebRTCOutput::Setup(msg))));
                }
            }
            WebRTCInput::Flush => {
                self.setup.send_queue().await?;
            }
            WebRTCInput::UpdateState => {
                return Ok(Some(WebRTCMessage::Output(WebRTCOutput::State(
                    self.setup.get_state().await?,
                ))));
            }
            WebRTCInput::Reset => self.setup.reset()?,
        }
        Ok(None)
    }
}

#[async_trait(?Send)]
impl SubsystemListener<WebRTCMessage> for WebRTCConnection {
    async fn messages(&mut self, msgs: Vec<WebRTCMessage>) -> Vec<(Destination, WebRTCMessage)> {
        let mut out = vec![];
        for msg in msgs {
            if let WebRTCMessage::Input(msg_in) = msg {
                match self.msg_in(msg_in).await {
                    Ok(Some(msg)) => out.push((Destination::Others, msg)),
                    Ok(None) => {}
                    Err(e) => {
                        log::warn!("Error processing message: {:?}", e);
                    }
                }
            }
        }
        out
    }
}

pub fn web_rtc_spawner() -> WebRTCSpawner {
    Box::new(|| Box::new(Box::pin(WebRTCConnection::new_box())))
}