201 lines
6.1 KiB
Rust
201 lines
6.1 KiB
Rust
// file: src/rtc_state.rs
|
|
|
|
use crate::rtc_types::{PeerInfo, RtcAction, RtcSnapshot};
|
|
use std::sync::Arc;
|
|
use tokio::sync::mpsc;
|
|
use webrtc::data_channel::RTCDataChannel;
|
|
use webrtc::peer_connection::RTCPeerConnection;
|
|
|
|
#[derive(Debug)]
|
|
pub struct RtcUiState {
|
|
pub signalling_connected: bool,
|
|
pub server_url: String,
|
|
pub display_name: String,
|
|
pub my_peer_id: Option<String>,
|
|
pub peers: Vec<PeerInfo>,
|
|
pub logs: Vec<String>,
|
|
pub chat_messages: Vec<String>,
|
|
pub rtc_messages: Vec<String>,
|
|
pub rtc_status: String,
|
|
pub data_channel_open: bool,
|
|
pub active_remote_peer_id: Option<String>,
|
|
}
|
|
|
|
impl RtcUiState {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
signalling_connected: false,
|
|
server_url: String::new(),
|
|
display_name: String::new(),
|
|
my_peer_id: None,
|
|
peers: Vec::new(),
|
|
logs: vec!["Ready.".to_string()],
|
|
chat_messages: vec!["No messages yet.".to_string()],
|
|
rtc_messages: vec!["No RTC messages yet.".to_string()],
|
|
rtc_status: "Idle.".to_string(),
|
|
data_channel_open: false,
|
|
active_remote_peer_id: None,
|
|
}
|
|
}
|
|
|
|
pub fn snapshot(&self) -> RtcSnapshot {
|
|
RtcSnapshot {
|
|
signalling_connected: self.signalling_connected,
|
|
server_url: self.server_url.clone(),
|
|
display_name: self.display_name.clone(),
|
|
my_peer_id: self.my_peer_id.clone(),
|
|
peers: self.peers.clone(),
|
|
logs: self.logs.clone(),
|
|
chat_messages: self.chat_messages.clone(),
|
|
rtc_messages: self.rtc_messages.clone(),
|
|
rtc_status: self.rtc_status.clone(),
|
|
data_channel_open: self.data_channel_open,
|
|
active_remote_peer_id: self.active_remote_peer_id.clone(),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct RtcRuntimeState {
|
|
pub signalling_tx: Option<mpsc::UnboundedSender<RtcAction>>,
|
|
pub peer_connection: Option<Arc<RTCPeerConnection>>,
|
|
pub data_channel: Option<Arc<RTCDataChannel>>,
|
|
}
|
|
|
|
impl RtcRuntimeState {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
signalling_tx: None,
|
|
peer_connection: None,
|
|
data_channel: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct RtcAppState {
|
|
pub ui: Arc<std::sync::Mutex<RtcUiState>>,
|
|
pub runtime: Arc<std::sync::Mutex<RtcRuntimeState>>,
|
|
}
|
|
|
|
impl RtcAppState {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
ui: Arc::new(std::sync::Mutex::new(RtcUiState::new())),
|
|
runtime: Arc::new(std::sync::Mutex::new(RtcRuntimeState::new())),
|
|
}
|
|
}
|
|
|
|
pub fn snapshot(&self) -> Result<RtcSnapshot, String> {
|
|
let lock_result = self.ui.lock();
|
|
match lock_result {
|
|
Ok(guard) => Ok(guard.snapshot()),
|
|
Err(_) => Err("rtc ui state lock poisoned".to_string()),
|
|
}
|
|
}
|
|
|
|
pub fn push_log(&self, line: String) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
guard.logs.push(line);
|
|
if guard.logs.len() > 200 {
|
|
let drain_len = guard.logs.len().saturating_sub(200);
|
|
guard.logs.drain(0..drain_len);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn push_chat_message(&self, line: String) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
if guard.chat_messages.len() == 1 && guard.chat_messages[0] == "No messages yet." {
|
|
guard.chat_messages.clear();
|
|
}
|
|
|
|
guard.chat_messages.push(line);
|
|
|
|
if guard.chat_messages.len() > 200 {
|
|
let drain_len = guard.chat_messages.len().saturating_sub(200);
|
|
guard.chat_messages.drain(0..drain_len);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn push_rtc_message(&self, line: String) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
if guard.rtc_messages.len() == 1 && guard.rtc_messages[0] == "No RTC messages yet." {
|
|
guard.rtc_messages.clear();
|
|
}
|
|
|
|
guard.rtc_messages.push(line);
|
|
|
|
if guard.rtc_messages.len() > 200 {
|
|
let drain_len = guard.rtc_messages.len().saturating_sub(200);
|
|
guard.rtc_messages.drain(0..drain_len);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn set_signalling_connected(&self, connected: bool) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
guard.signalling_connected = connected;
|
|
}
|
|
}
|
|
|
|
pub fn set_server_info(&self, server_url: String, display_name: String) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
guard.server_url = server_url;
|
|
guard.display_name = display_name;
|
|
}
|
|
}
|
|
|
|
pub fn set_my_peer_id(&self, peer_id: Option<String>) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
guard.my_peer_id = peer_id;
|
|
}
|
|
}
|
|
|
|
pub fn set_peers(&self, peers: Vec<PeerInfo>) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
guard.peers = peers;
|
|
}
|
|
}
|
|
|
|
pub fn set_rtc_status(&self, status: String) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
guard.rtc_status = status;
|
|
}
|
|
}
|
|
|
|
pub fn set_data_channel_open(&self, open: bool) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
guard.data_channel_open = open;
|
|
}
|
|
}
|
|
|
|
pub fn set_active_remote_peer_id(&self, peer_id: Option<String>) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
guard.active_remote_peer_id = peer_id;
|
|
}
|
|
}
|
|
|
|
pub fn clear_after_disconnect(&self) {
|
|
let lock_result = self.ui.lock();
|
|
if let Ok(mut guard) = lock_result {
|
|
guard.signalling_connected = false;
|
|
guard.my_peer_id = None;
|
|
guard.peers.clear();
|
|
guard.rtc_status = "Idle.".to_string();
|
|
guard.data_channel_open = false;
|
|
guard.active_remote_peer_id = None;
|
|
}
|
|
}
|
|
}
|