Compare commits

...

2 Commits

Author SHA1 Message Date
Baud c30913f823 feat: Deserializing commands 2024-02-24 17:01:28 +00:00
Baud c80d7643ca feat: Program Input deserialization 2024-02-23 11:40:57 +00:00
5 changed files with 67 additions and 57 deletions

View File

@ -346,7 +346,7 @@ impl AtemSocketInner {
self.send_or_queue_ack().await;
if length > 12 {
self.on_command_received(&packet[12..]);
self.on_commands_received(&packet[12..]);
}
} else if self
.is_packet_covered_by_ack(self.last_received_packed_id, remote_packet_id)
@ -464,7 +464,7 @@ impl AtemSocketInner {
}
}
fn on_command_received(&mut self, payload: &[u8]) {
fn on_commands_received(&mut self, payload: &[u8]) {
let commands = deserialize_commands(payload);
}

View File

@ -1,17 +1,13 @@
use std::{collections::HashMap, sync::Arc};
use std::{collections::HashMap, fmt::Debug, sync::Arc};
use crate::{enums::ProtocolVersion, state::AtemState};
pub trait DeserializedCommand: Send + Sync {
fn deserialize(buffer: &[u8]) -> Self
where
Self: Sized;
pub trait DeserializedCommand: Send + Sync + Debug {
fn apply_to_state(&self, state: &mut AtemState) -> Vec<String>;
}
pub trait DeserializableCommand: DeserializedCommand {
fn get_raw_name(&self) -> &'static str;
fn get_minimum_version(&self) -> ProtocolVersion;
pub trait CommandDeserializer: Send + Sync {
fn deserialize(&self, buffer: &[u8]) -> Arc<dyn DeserializedCommand>;
}
pub trait SerializableCommand {
@ -19,7 +15,7 @@ pub trait SerializableCommand {
}
pub trait BasicWritableCommand: SerializableCommand {
fn get_raw_name(&self) -> &'static str;
fn get_raw_name() -> &'static str;
fn get_minimum_version(&self) -> ProtocolVersion;
}
@ -28,5 +24,3 @@ pub trait WritableCommand: BasicWritableCommand {
fn get_flag(&self) -> f64;
fn set_flag(&mut self, flag: f64);
}
pub trait SymmetricalCommand: DeserializableCommand + SerializableCommand {}

View File

@ -1,9 +1,13 @@
use crate::commands::command_base::{BasicWritableCommand, SerializableCommand};
use std::sync::Arc;
#[derive(new)]
use crate::commands::command_base::{
BasicWritableCommand, CommandDeserializer, DeserializedCommand, SerializableCommand,
};
#[derive(Debug, new)]
pub struct ProgramInput {
mix_effect: u8,
source: u16,
pub mix_effect: u8,
pub source: u16,
}
impl SerializableCommand for ProgramInput {
@ -17,7 +21,7 @@ impl SerializableCommand for ProgramInput {
}
impl BasicWritableCommand for ProgramInput {
fn get_raw_name(&self) -> &'static str {
fn get_raw_name() -> &'static str {
"CPgI"
}
@ -25,3 +29,21 @@ impl BasicWritableCommand for ProgramInput {
crate::enums::ProtocolVersion::Unknown
}
}
impl DeserializedCommand for ProgramInput {
fn apply_to_state(&self, state: &mut crate::state::AtemState) -> Vec<String> {
todo!()
}
}
#[derive(Default)]
pub struct ProgramInputDeserializer {}
impl CommandDeserializer for ProgramInputDeserializer {
fn deserialize(&self, buffer: &[u8]) -> Arc<dyn DeserializedCommand> {
let mix_effect = buffer[0];
let source = u16::from_be_bytes([buffer[2], buffer[3]]);
Arc::new(ProgramInput { mix_effect, source })
}
}

View File

@ -1,15 +1,16 @@
use std::sync::Arc;
use std::{collections::VecDeque, sync::Arc};
use crate::commands::tally_by_source::TallyBySource;
use super::{
command_base::{CommandDeserializer, DeserializedCommand},
mix_effects::program_input::ProgramInputDeserializer,
tally_by_source::TallyBySourceDeserializer,
};
use super::command_base::DeserializedCommand;
pub fn deserialize_commands(payload: &[u8]) -> Vec<Arc<dyn DeserializedCommand>> {
let mut parsed_commands = vec![];
pub fn deserialize_commands(payload: &[u8]) -> VecDeque<Arc<dyn DeserializedCommand>> {
let mut parsed_commands = VecDeque::new();
let mut head = 0;
while payload.len() > head + 8 {
// log::debug!("Head at {} out of {}", head, payload.len());
let length = u16::from_be_bytes([payload[head], payload[head + 1]]) as usize;
let Ok(name) = String::from_utf8(payload[(head + 4)..(head + 8)].to_vec()) else {
break;
@ -21,19 +22,10 @@ pub fn deserialize_commands(payload: &[u8]) -> Vec<Arc<dyn DeserializedCommand>>
log::debug!("Received command {} with length {}", name, length);
match name.as_str() {
"TlSr" => {
let tally = TallyBySource::deserialize(&payload[head + 8..head + length]);
for (source, state) in tally.sources {
log::info!(
"Source {} Program: {}, Preview: {}",
source,
state.program,
state.preview
)
}
}
_ => {}
if let Some(deserializer) = command_deserializer_from_string(name.as_str()) {
let deserialized_command = deserializer.deserialize(&payload[head + 8..head + length]);
log::debug!("Received {:?}", deserialized_command);
parsed_commands.push_back(deserialized_command);
}
head += length;
@ -41,3 +33,11 @@ pub fn deserialize_commands(payload: &[u8]) -> Vec<Arc<dyn DeserializedCommand>>
parsed_commands
}
fn command_deserializer_from_string(command_str: &str) -> Option<Box<dyn CommandDeserializer>> {
match command_str {
"PrgI" => Some(Box::<ProgramInputDeserializer>::default()),
"TlSr" => Some(Box::<TallyBySourceDeserializer>::default()),
_ => None,
}
}

View File

@ -1,31 +1,29 @@
use std::collections::HashMap;
use std::{collections::HashMap, sync::Arc};
use crate::commands::command_base::{BasicWritableCommand, SerializableCommand};
use super::command_base::{DeserializableCommand, DeserializedCommand};
use super::command_base::{CommandDeserializer, DeserializedCommand};
#[derive(Debug)]
pub struct TallySource {
pub program: bool,
pub preview: bool,
}
#[derive(new)]
#[derive(Debug, new)]
pub struct TallyBySource {
pub sources: HashMap<u16, TallySource>,
}
impl DeserializableCommand for TallyBySource {
fn get_raw_name(&self) -> &'static str {
"TlSr"
}
fn get_minimum_version(&self) -> crate::enums::ProtocolVersion {
crate::enums::ProtocolVersion::Unknown
impl DeserializedCommand for TallyBySource {
fn apply_to_state(&self, state: &mut crate::state::AtemState) -> Vec<String> {
todo!()
}
}
impl DeserializedCommand for TallyBySource {
fn deserialize(buffer: &[u8]) -> Self {
#[derive(Default)]
pub struct TallyBySourceDeserializer {}
impl CommandDeserializer for TallyBySourceDeserializer {
fn deserialize(&self, buffer: &[u8]) -> Arc<dyn DeserializedCommand> {
let source_count = u16::from_be_bytes([buffer[0], buffer[1]]) as usize;
log::debug!("{:?}", buffer);
@ -47,10 +45,6 @@ impl DeserializedCommand for TallyBySource {
);
}
Self { sources }
}
fn apply_to_state(&self, state: &mut crate::state::AtemState) -> Vec<String> {
todo!()
Arc::new(TallyBySource { sources })
}
}