chore: Various cleanups
This commit is contained in:
parent
2bbf2c5c6b
commit
90b2cfd984
|
@ -4,7 +4,7 @@ use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use tokio::sync::{mpsc::error::TryRecvError, Semaphore};
|
use tokio::{select, sync::Semaphore};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -61,11 +61,10 @@ impl Atem {
|
||||||
let mut state = AtemState::default();
|
let mut state = AtemState::default();
|
||||||
|
|
||||||
while !cancel.is_cancelled() {
|
while !cancel.is_cancelled() {
|
||||||
match atem_event_rx.try_recv() {
|
select! {
|
||||||
Ok(event) => match event {
|
_ = cancel.cancelled() => {},
|
||||||
AtemEvent::Error(_) => todo!(),
|
message = atem_event_rx.recv() => match message {
|
||||||
AtemEvent::Info(_) => todo!(),
|
Some(event) => match event {
|
||||||
AtemEvent::Debug(_) => todo!(),
|
|
||||||
AtemEvent::Connected => {
|
AtemEvent::Connected => {
|
||||||
log::info!("Atem connected");
|
log::info!("Atem connected");
|
||||||
}
|
}
|
||||||
|
@ -84,14 +83,14 @@ impl Atem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(TryRecvError::Empty) => {}
|
None => {
|
||||||
Err(TryRecvError::Disconnected) => {
|
|
||||||
log::info!("ATEM event channel has closed, exiting event loop.");
|
log::info!("ATEM event channel has closed, exiting event loop.");
|
||||||
cancel.cancel();
|
cancel.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn send_commands(&self, commands: Vec<Box<dyn BasicWritableCommand>>) {
|
pub async fn send_commands(&self, commands: Vec<Box<dyn BasicWritableCommand>>) {
|
||||||
let (callback_tx, callback_rx) = tokio::sync::oneshot::channel();
|
let (callback_tx, callback_rx) = tokio::sync::oneshot::channel();
|
||||||
|
|
|
@ -9,8 +9,8 @@ use std::{
|
||||||
|
|
||||||
use tokio::{
|
use tokio::{
|
||||||
net::UdpSocket,
|
net::UdpSocket,
|
||||||
|
select,
|
||||||
sync::{Barrier, Mutex},
|
sync::{Barrier, Mutex},
|
||||||
task::yield_now,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -55,9 +55,6 @@ pub struct TrackingIdsCallback {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum AtemEvent {
|
pub enum AtemEvent {
|
||||||
Error(String),
|
|
||||||
Info(String),
|
|
||||||
Debug(String),
|
|
||||||
Connected,
|
Connected,
|
||||||
Disconnected,
|
Disconnected,
|
||||||
ReceivedCommands(VecDeque<Arc<dyn DeserializedCommand>>),
|
ReceivedCommands(VecDeque<Arc<dyn DeserializedCommand>>),
|
||||||
|
@ -179,12 +176,14 @@ impl AtemSocket {
|
||||||
cancel: tokio_util::sync::CancellationToken,
|
cancel: tokio_util::sync::CancellationToken,
|
||||||
) {
|
) {
|
||||||
while !cancel.is_cancelled() {
|
while !cancel.is_cancelled() {
|
||||||
if let Ok(msg) = atem_message_rx.try_recv() {
|
select! {
|
||||||
match msg {
|
_ = cancel.cancelled() => {},
|
||||||
AtemSocketMessage::Connect {
|
message = atem_message_rx.recv() => {
|
||||||
|
match message {
|
||||||
|
Some(AtemSocketMessage::Connect {
|
||||||
address,
|
address,
|
||||||
result_callback,
|
result_callback,
|
||||||
} => {
|
}) => {
|
||||||
{
|
{
|
||||||
let mut connected_callbacks = self.connected_callbacks.lock().await;
|
let mut connected_callbacks = self.connected_callbacks.lock().await;
|
||||||
connected_callbacks.push(result_callback);
|
connected_callbacks.push(result_callback);
|
||||||
|
@ -196,11 +195,11 @@ impl AtemSocket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AtemSocketMessage::Disconnect => self.disconnect(),
|
Some(AtemSocketMessage::Disconnect) => self.disconnect(),
|
||||||
AtemSocketMessage::SendCommands {
|
Some(AtemSocketMessage::SendCommands {
|
||||||
commands,
|
commands,
|
||||||
tracking_ids_callback,
|
tracking_ids_callback,
|
||||||
} => {
|
}) => {
|
||||||
let barrier = Arc::new(Barrier::new(2));
|
let barrier = Arc::new(Barrier::new(2));
|
||||||
tracking_ids_callback
|
tracking_ids_callback
|
||||||
.send(TrackingIdsCallback {
|
.send(TrackingIdsCallback {
|
||||||
|
@ -225,15 +224,18 @@ impl AtemSocket {
|
||||||
// actor we're waiting on doesn't take _too_ long to do ✨ shenanigans ✨ before signalling that
|
// actor we're waiting on doesn't take _too_ long to do ✨ shenanigans ✨ before signalling that
|
||||||
// they are ready. If they do, I suggest finding whoever wrote that code and bonking them 🔨.
|
// they are ready. If they do, I suggest finding whoever wrote that code and bonking them 🔨.
|
||||||
barrier.wait().await;
|
barrier.wait().await;
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
log::info!("ATEM message channel has closed, exiting event loop.");
|
||||||
|
cancel.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
yield_now().await;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tick().await;
|
self.tick().await;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn connect(&mut self, address: SocketAddr) -> Result<(), io::Error> {
|
pub async fn connect(&mut self, address: SocketAddr) -> Result<(), io::Error> {
|
||||||
let socket = UdpSocket::bind("0.0.0.0:0").await?;
|
let socket = UdpSocket::bind("0.0.0.0:0").await?;
|
||||||
|
@ -316,7 +318,7 @@ impl AtemSocket {
|
||||||
|
|
||||||
async fn restart_connection(&mut self) {
|
async fn restart_connection(&mut self) {
|
||||||
self.disconnect();
|
self.disconnect();
|
||||||
self.connect(self.address.clone()).await.ok();
|
self.connect(self.address).await.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn tick(&mut self) {
|
async fn tick(&mut self) {
|
||||||
|
@ -470,7 +472,7 @@ impl AtemSocket {
|
||||||
let flag: u8 = PacketFlag::AckReply.into();
|
let flag: u8 = PacketFlag::AckReply.into();
|
||||||
let opcode = u16::from(flag) << 11;
|
let opcode = u16::from(flag) << 11;
|
||||||
let mut buffer: [u8; ACK_PACKET_LENGTH as _] = [0; 12];
|
let mut buffer: [u8; ACK_PACKET_LENGTH as _] = [0; 12];
|
||||||
buffer[0..2].copy_from_slice(&u16::to_be_bytes(opcode as u16 | ACK_PACKET_LENGTH));
|
buffer[0..2].copy_from_slice(&u16::to_be_bytes(opcode | ACK_PACKET_LENGTH));
|
||||||
buffer[2..4].copy_from_slice(&u16::to_be_bytes(self.session_id));
|
buffer[2..4].copy_from_slice(&u16::to_be_bytes(self.session_id));
|
||||||
buffer[4..6].copy_from_slice(&u16::to_be_bytes(packet_id));
|
buffer[4..6].copy_from_slice(&u16::to_be_bytes(packet_id));
|
||||||
self.send_packet(&buffer).await;
|
self.send_packet(&buffer).await;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{enums::ProtocolVersion, state::AtemState};
|
||||||
|
|
||||||
pub trait DeserializedCommand: Send + Sync + Debug {
|
pub trait DeserializedCommand: Send + Sync + Debug {
|
||||||
fn raw_name(&self) -> &'static str;
|
fn raw_name(&self) -> &'static str;
|
||||||
fn apply_to_state(&self, state: &mut AtemState) -> bool;
|
fn apply_to_state(&self, state: &mut AtemState);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CommandDeserializer: Send + Sync {
|
pub trait CommandDeserializer: Send + Sync {
|
||||||
|
|
|
@ -16,8 +16,8 @@ impl DeserializedCommand for VersionCommand {
|
||||||
DESERIALIZE_VERSION_RAW_NAME
|
DESERIALIZE_VERSION_RAW_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_to_state(&self, state: &mut crate::state::AtemState) -> bool {
|
fn apply_to_state(&self, state: &mut crate::state::AtemState) {
|
||||||
todo!("Apply to state: Version")
|
state.info.api_version = self.version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ impl DeserializedCommand for InitComplete {
|
||||||
DESERIALIZE_INIT_COMPLETE_RAW_NAME
|
DESERIALIZE_INIT_COMPLETE_RAW_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_to_state(&self, state: &mut crate::state::AtemState) -> bool {
|
fn apply_to_state(&self, state: &mut crate::state::AtemState) {
|
||||||
todo!("Apply to state: Init Complete")
|
todo!("Apply to state: Init Complete")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl DeserializedCommand for ProgramInput {
|
||||||
DESERIALIZE_PROGRAM_INPUT_RAW_NAME
|
DESERIALIZE_PROGRAM_INPUT_RAW_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_to_state(&self, state: &mut crate::state::AtemState) -> bool {
|
fn apply_to_state(&self, state: &mut crate::state::AtemState) {
|
||||||
todo!("Apply to state: Program Input")
|
todo!("Apply to state: Program Input")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ impl DeserializedCommand for TallyBySource {
|
||||||
DESERIALIZE_TALLY_BY_SOURCE_RAW_NAME
|
DESERIALIZE_TALLY_BY_SOURCE_RAW_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_to_state(&self, state: &mut crate::state::AtemState) -> bool {
|
fn apply_to_state(&self, state: &mut crate::state::AtemState) {
|
||||||
todo!("Apply to state: Tally By Source")
|
todo!("Apply to state: Tally By Source")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,7 @@ impl DeserializedCommand for Time {
|
||||||
DESERIALIZE_TIME_RAW_NAME
|
DESERIALIZE_TIME_RAW_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_to_state(&self, state: &mut crate::state::AtemState) -> bool {
|
fn apply_to_state(&self, state: &mut crate::state::AtemState) {}
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub enum Model {
|
||||||
MiniExtremeISO = 0x11,
|
MiniExtremeISO = 0x11,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
||||||
pub enum ProtocolVersion {
|
pub enum ProtocolVersion {
|
||||||
#[default]
|
#[default]
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
|
|
|
@ -16,16 +16,16 @@ pub mod video;
|
||||||
|
|
||||||
#[derive(Default, Clone, PartialEq)]
|
#[derive(Default, Clone, PartialEq)]
|
||||||
pub struct AtemState {
|
pub struct AtemState {
|
||||||
info: info::DeviceInfo,
|
pub info: info::DeviceInfo,
|
||||||
video: video::AtemVideoState,
|
pub video: video::AtemVideoState,
|
||||||
audio: Option<audio::AtemClassicAudioState>,
|
pub audio: Option<audio::AtemClassicAudioState>,
|
||||||
fairlight: Option<fairlight::AtemFairlightAudioState>,
|
pub fairlight: Option<fairlight::AtemFairlightAudioState>,
|
||||||
media: media::MediaState,
|
pub media: media::MediaState,
|
||||||
inputs: HashMap<u64, input::InputChannel>,
|
pub inputs: HashMap<u64, input::InputChannel>,
|
||||||
// macro is a rust keyword
|
// macro is a rust keyword
|
||||||
atem_macro: atem_macro::MacroState,
|
pub atem_macro: atem_macro::MacroState,
|
||||||
settings: settings::SettingsState,
|
pub settings: settings::SettingsState,
|
||||||
recording: Option<recording::RecordingState>,
|
pub recording: Option<recording::RecordingState>,
|
||||||
streaming: Option<streaming::StreamingState>,
|
pub streaming: Option<streaming::StreamingState>,
|
||||||
color_generators: HashMap<u64, color::ColorGeneratorState>,
|
pub color_generators: HashMap<u64, color::ColorGeneratorState>,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue