feat: Deserializing commands
This commit is contained in:
parent
c80d7643ca
commit
c30913f823
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::commands::command_base::{
|
||||
BasicWritableCommand, DeserializableCommand, DeserializedCommand, SerializableCommand,
|
||||
BasicWritableCommand, CommandDeserializer, DeserializedCommand, SerializableCommand,
|
||||
};
|
||||
|
||||
#[derive(new)]
|
||||
#[derive(Debug, new)]
|
||||
pub struct ProgramInput {
|
||||
pub mix_effect: u8,
|
||||
pub source: u16,
|
||||
|
@ -19,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"
|
||||
}
|
||||
|
||||
|
@ -28,28 +30,20 @@ impl BasicWritableCommand for ProgramInput {
|
|||
}
|
||||
}
|
||||
|
||||
impl DeserializableCommand for ProgramInput {
|
||||
fn get_raw_name(&self) -> &'static str {
|
||||
"PrgI"
|
||||
}
|
||||
|
||||
fn get_minimum_version(&self) -> crate::enums::ProtocolVersion {
|
||||
crate::enums::ProtocolVersion::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
impl DeserializedCommand for ProgramInput {
|
||||
fn deserialize(buffer: &[u8]) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let mix_effect = buffer[0];
|
||||
let source = u16::from_be_bytes([buffer[2], buffer[3]]);
|
||||
|
||||
Self { mix_effect, source }
|
||||
}
|
||||
|
||||
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 })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
use std::sync::Arc;
|
||||
use std::{collections::VecDeque, sync::Arc};
|
||||
|
||||
use crate::commands::{mix_effects::program_input::ProgramInput, 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,28 +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
|
||||
)
|
||||
}
|
||||
}
|
||||
"PrgI" => {
|
||||
let program_input = ProgramInput::deserialize(&payload[head + 8..head + length]);
|
||||
|
||||
log::info!(
|
||||
"Mix Effect {} changed to source {}",
|
||||
program_input.mix_effect,
|
||||
program_input.source
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
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;
|
||||
|
@ -50,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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 deserialize(buffer: &[u8]) -> Self {
|
||||
fn apply_to_state(&self, state: &mut crate::state::AtemState) -> Vec<String> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[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 })
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue