From 2325645bb58b94aa919bac6786aeb96f98abaad3 Mon Sep 17 00:00:00 2001 From: Baud Date: Mon, 11 Mar 2024 00:30:16 +0000 Subject: [PATCH] feat: Handle program input --- .../src/commands/init_complete.rs | 6 ++-- .../src/commands/mix_effects/program_input.rs | 18 ++++++++-- atem-connection-rs/src/state/info.rs | 2 +- atem-connection-rs/src/state/util.rs | 34 ++++++++++++++++++- atem-connection-rs/src/state/video/mod.rs | 12 +++++-- 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/atem-connection-rs/src/commands/init_complete.rs b/atem-connection-rs/src/commands/init_complete.rs index 43b934e..e8380db 100644 --- a/atem-connection-rs/src/commands/init_complete.rs +++ b/atem-connection-rs/src/commands/init_complete.rs @@ -12,16 +12,14 @@ impl DeserializedCommand for InitComplete { DESERIALIZE_INIT_COMPLETE_RAW_NAME } - fn apply_to_state(&self, state: &mut crate::state::AtemState) { - todo!("Apply to state: Init Complete") - } + fn apply_to_state(&self, _state: &mut crate::state::AtemState) {} } #[derive(Default)] pub struct InitCompleteDeserializer {} impl CommandDeserializer for InitCompleteDeserializer { - fn deserialize(&self, buffer: &[u8]) -> std::sync::Arc { + fn deserialize(&self, _buffer: &[u8]) -> std::sync::Arc { Arc::new(InitComplete {}) } } diff --git a/atem-connection-rs/src/commands/mix_effects/program_input.rs b/atem-connection-rs/src/commands/mix_effects/program_input.rs index c51eb82..53c30c5 100644 --- a/atem-connection-rs/src/commands/mix_effects/program_input.rs +++ b/atem-connection-rs/src/commands/mix_effects/program_input.rs @@ -1,7 +1,10 @@ use std::sync::Arc; -use crate::commands::command_base::{ - BasicWritableCommand, CommandDeserializer, DeserializedCommand, SerializableCommand, +use crate::{ + commands::command_base::{ + BasicWritableCommand, CommandDeserializer, DeserializedCommand, SerializableCommand, + }, + state::util::get_mix_effect, }; pub const DESERIALIZE_PROGRAM_INPUT_RAW_NAME: &str = "PrgI"; @@ -38,7 +41,16 @@ impl DeserializedCommand for ProgramInput { } fn apply_to_state(&self, state: &mut crate::state::AtemState) { - todo!("Apply to state: Program Input") + let Some(capabilities) = state.info.capabilities() else { + todo!("Return error"); + }; + + if self.mix_effect > *capabilities.mix_effects() { + todo!("Return error"); + } + + let mix_effect = get_mix_effect(state, self.mix_effect as usize); + mix_effect.program_input = self.source; } } diff --git a/atem-connection-rs/src/state/info.rs b/atem-connection-rs/src/state/info.rs index 43a4b16..ce564cc 100644 --- a/atem-connection-rs/src/state/info.rs +++ b/atem-connection-rs/src/state/info.rs @@ -2,7 +2,7 @@ use crate::enums::{Model, ProtocolVersion}; #[derive(Clone, PartialEq, Getters, new)] pub struct AtemCapabilites { - mix_effects: u64, + mix_effects: u8, sources: u64, auxilliaries: u64, mix_minus_outputs: u64, diff --git a/atem-connection-rs/src/state/util.rs b/atem-connection-rs/src/state/util.rs index 914821d..776e7b5 100644 --- a/atem-connection-rs/src/state/util.rs +++ b/atem-connection-rs/src/state/util.rs @@ -1,9 +1,41 @@ -use super::{settings::MultiViewer, AtemState}; +use crate::enums::{TransitionSelection, TransitionStyle}; + +use super::{ + settings::MultiViewer, + video::{MixEffect, TransitionPosition, TransitionProperties, TransitionSettings}, + AtemState, +}; pub fn create() -> AtemState { AtemState::default() } +pub fn get_mix_effect(state: &mut AtemState, index: usize) -> &mut MixEffect { + // TODO: Use of index here is terrible and dangerous + + if state.video.mix_effects().get(index).is_none() { + let mix_effect = MixEffect::new( + index, + 0, + 0, + false, + None, + TransitionPosition::new(false, 0.0, 0.0), + TransitionProperties::new( + TransitionStyle::MIX, + vec![TransitionSelection::Background], + TransitionStyle::MIX, + vec![TransitionSelection::Background], + ), + TransitionSettings::new(None, None, None, None, None), + vec![], + ); + state.video.mix_effects_mut()[index] = mix_effect.clone(); + }; + + &mut state.video.mix_effects_mut()[index] +} + pub fn get_multi_viewer(state: &mut AtemState, index: usize) -> Option<&MultiViewer> { state.settings.multi_viewers().get(index) } diff --git a/atem-connection-rs/src/state/video/mod.rs b/atem-connection-rs/src/state/video/mod.rs index 8085848..fba70b5 100644 --- a/atem-connection-rs/src/state/video/mod.rs +++ b/atem-connection-rs/src/state/video/mod.rs @@ -87,9 +87,9 @@ pub struct TransitionPosition { #[derive(Clone, PartialEq, Getters, new)] pub struct MixEffect { - index: f64, - pub program_input: f64, - pub preview_input: f64, + index: usize, + pub program_input: u16, + pub preview_input: u16, pub transition_preview: bool, pub fade_to_black: Option, pub transition_position: TransitionPosition, @@ -113,3 +113,9 @@ pub struct AtemVideoState { auxiliaries: Vec, super_sources: Vec, } + +impl AtemVideoState { + pub fn mix_effects_mut(&mut self) -> &mut Vec { + &mut self.mix_effects + } +}