♻️ refactor(pmowebrenderer): factoriser handlers et supprimer duplications
- Remplacer les Arc+Box::pin manuels par la macro action_handler!(captures(...)) - Supprimer helpers locaux dupliqués dans renderer.rs (add_var, add_action) - Extraire handlers génériques pour GET requests - Factoriser extraction metadata dans set_uri_handler /set_next_uriHandler - Simplifier build_renderingcontrol en retirant pipeline inutile - Mettre à jour edition Rust de 2021 vers 2024 dans tous les Cargo.toml - Corriger pattern matching inutile `ref` sur déréférencement dans pmoaudio et pmoflac
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "pmowebrenderer"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
pmoupnp = { path = "../pmoupnp" }
|
||||
|
||||
@@ -3,316 +3,197 @@
|
||||
//! Chaque handler bridge une action UPnP vers une commande `PipelineControl`
|
||||
//! envoyée au pipeline audio serveur, ou lit l'état partagé pour les requêtes GET.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use pmodidl::DIDLLite;
|
||||
use pmoupnp::actions::{ActionData, ActionError, ActionHandler, get_value};
|
||||
use pmoupnp::{get, set};
|
||||
use pmodidl::ToXmlElement;
|
||||
use pmoupnp::{action_handler, get, set};
|
||||
use pmoupnp::actions::{get_value, ActionHandler};
|
||||
|
||||
use crate::messages::PlaybackState;
|
||||
use crate::pipeline::{PipelineControl, PipelineHandle, upnp_time_to_seconds};
|
||||
use crate::pipeline::{upnp_time_to_seconds, PipelineControl, PipelineHandle};
|
||||
use crate::state::SharedState;
|
||||
|
||||
type ActionFuture =
|
||||
std::pin::Pin<Box<dyn std::future::Future<Output = Result<ActionData, ActionError>> + Send>>;
|
||||
// ─── AVTransport : commandes de transport ─────────────────────────────────────
|
||||
|
||||
// ─── AVTransport Handlers ───────────────────────────────────────────────────
|
||||
|
||||
/// Handler pour l'action UPnP "Play" - lance la lecture du flux audio
|
||||
pub fn play_handler(pipeline: PipelineHandle, state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let pipeline = pipeline.clone();
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
tracing::info!("[WebRenderer] UPnP Play action invoked");
|
||||
let has_uri = state.read().current_uri.is_some();
|
||||
{
|
||||
let mut s = state.write();
|
||||
s.playback_state = PlaybackState::Transitioning;
|
||||
}
|
||||
if has_uri {
|
||||
state.write().player_command = Some(serde_json::json!({
|
||||
"type": "stream",
|
||||
"url": "/api/webrenderer/stream"
|
||||
}));
|
||||
tracing::info!("UPnP Play: stored stream command for frontend polling");
|
||||
}
|
||||
pipeline.send(PipelineControl::Play).await;
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(captures(pipeline, state) |data| {
|
||||
tracing::info!("[WebRenderer] UPnP Play action invoked");
|
||||
let has_uri = state.read().current_uri.is_some();
|
||||
state.write().playback_state = PlaybackState::Transitioning;
|
||||
if has_uri {
|
||||
state.write().player_command = Some(serde_json::json!({
|
||||
"type": "stream",
|
||||
"url": "/api/webrenderer/stream"
|
||||
}));
|
||||
tracing::info!("UPnP Play: stored stream command for frontend polling");
|
||||
}
|
||||
pipeline.send(PipelineControl::Play).await;
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "Stop" - arrête la lecture
|
||||
pub fn stop_handler(pipeline: PipelineHandle, state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let pipeline = pipeline.clone();
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
pipeline.send(PipelineControl::Stop).await;
|
||||
state.write().playback_state = PlaybackState::Stopped;
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(captures(pipeline, state) |data| {
|
||||
pipeline.send(PipelineControl::Stop).await;
|
||||
state.write().playback_state = PlaybackState::Stopped;
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "Pause" - met en pause la lecture
|
||||
pub fn pause_handler(pipeline: PipelineHandle, state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let pipeline = pipeline.clone();
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
pipeline.send(PipelineControl::Pause).await;
|
||||
state.write().playback_state = PlaybackState::Paused;
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(captures(pipeline, state) |data| {
|
||||
pipeline.send(PipelineControl::Pause).await;
|
||||
state.write().playback_state = PlaybackState::Paused;
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "Next" - passe à la piste suivante
|
||||
pub fn next_handler(pipeline: PipelineHandle) -> ActionHandler {
|
||||
let pipeline = pipeline.clone();
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let pipeline = pipeline.clone();
|
||||
Box::pin(async move {
|
||||
pipeline.send(PipelineControl::Play).await;
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(captures(pipeline) |data| {
|
||||
pipeline.send(PipelineControl::Play).await;
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "Previous" - retourne au début de la piste actuelle
|
||||
pub fn previous_handler(pipeline: PipelineHandle) -> ActionHandler {
|
||||
let pipeline = pipeline.clone();
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let pipeline = pipeline.clone();
|
||||
Box::pin(async move {
|
||||
pipeline.send(PipelineControl::Play).await;
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(captures(pipeline) |data| {
|
||||
pipeline.send(PipelineControl::Play).await;
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "Seek" - seek à une position donnée
|
||||
pub fn seek_handler(pipeline: PipelineHandle) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let pipeline = pipeline.clone();
|
||||
Box::pin(async move {
|
||||
let target: String = get!(&data, "Target", String);
|
||||
let pos_sec = upnp_time_to_seconds(&target);
|
||||
pipeline.send(PipelineControl::Seek(pos_sec)).await;
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(captures(pipeline) |data| {
|
||||
let target: String = get!(&data, "Target", String);
|
||||
let pos_sec = upnp_time_to_seconds(&target);
|
||||
pipeline.send(PipelineControl::Seek(pos_sec)).await;
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "SetAVTransportURI" - définit l'URI à jouer
|
||||
// ─── AVTransport : chargement de média ────────────────────────────────────────
|
||||
|
||||
pub fn set_uri_handler(pipeline: PipelineHandle, state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let pipeline = pipeline.clone();
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
tracing::info!("[WebRenderer] UPnP SetAVTransportURI action invoked");
|
||||
let uri: String = get!(&data, "CurrentURI", String);
|
||||
let metadata: String = get_value::<String>(&data, "CurrentURIMetaData")
|
||||
.or_else(|_| {
|
||||
get_value::<DIDLLite>(&data, "CurrentURIMetaData")
|
||||
.map(|didl| didl.to_xml())
|
||||
})
|
||||
.unwrap_or_default();
|
||||
action_handler!(captures(pipeline, state) |mut data| {
|
||||
tracing::info!("[WebRenderer] UPnP SetAVTransportURI action invoked");
|
||||
let uri: String = get!(&data, "CurrentURI", String);
|
||||
let metadata: String = get_value::<String>(&data, "CurrentURIMetaData")
|
||||
.or_else(|_| get_value::<DIDLLite>(&data, "CurrentURIMetaData").map(|didl| didl.to_xml()))
|
||||
.unwrap_or_default();
|
||||
|
||||
tracing::info!(uri = %uri, "SetAVTransportURI handler called - loading URI into pipeline");
|
||||
pipeline.send(PipelineControl::LoadUri(uri.clone())).await;
|
||||
tracing::info!(uri = %uri, "SetAVTransportURI handler called - loading URI into pipeline");
|
||||
pipeline.send(PipelineControl::LoadUri(uri.clone())).await;
|
||||
|
||||
{
|
||||
let mut s = state.write();
|
||||
s.current_uri = Some(uri);
|
||||
s.current_metadata = Some(metadata);
|
||||
s.playback_state = PlaybackState::Transitioning;
|
||||
}
|
||||
Ok(data)
|
||||
})
|
||||
{
|
||||
let mut s = state.write();
|
||||
s.current_uri = Some(uri);
|
||||
s.current_metadata = Some(metadata);
|
||||
s.playback_state = PlaybackState::Transitioning;
|
||||
}
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "SetNextAVTransportURI" - définit l'URI suivante (gapless)
|
||||
pub fn set_next_uri_handler(pipeline: PipelineHandle, state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let pipeline = pipeline.clone();
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
let uri: String = get!(&data, "NextURI", String);
|
||||
let metadata: String = get_value::<String>(&data, "NextURIMetaData")
|
||||
.or_else(|_| {
|
||||
get_value::<DIDLLite>(&data, "NextURIMetaData")
|
||||
.map(|didl| didl.to_xml())
|
||||
})
|
||||
.unwrap_or_default();
|
||||
action_handler!(captures(pipeline, state) |mut data| {
|
||||
let uri: String = get!(&data, "NextURI", String);
|
||||
let metadata: String = get_value::<String>(&data, "NextURIMetaData")
|
||||
.or_else(|_| get_value::<DIDLLite>(&data, "NextURIMetaData").map(|didl| didl.to_xml()))
|
||||
.unwrap_or_default();
|
||||
|
||||
pipeline.send(PipelineControl::LoadNextUri(uri.clone())).await;
|
||||
|
||||
{
|
||||
let mut s = state.write();
|
||||
s.next_uri = Some(uri);
|
||||
s.next_metadata = Some(metadata);
|
||||
}
|
||||
Ok(data)
|
||||
})
|
||||
pipeline.send(PipelineControl::LoadNextUri(uri.clone())).await;
|
||||
{
|
||||
let mut s = state.write();
|
||||
s.next_uri = Some(uri);
|
||||
s.next_metadata = Some(metadata);
|
||||
}
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "GetPositionInfo" - retourne la position actuelle
|
||||
// ─── AVTransport : getters ─────────────────────────────────────────────────────
|
||||
|
||||
pub fn get_position_info_handler(state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
let mut data = data;
|
||||
let s = state.read();
|
||||
set!(
|
||||
&mut data,
|
||||
"Track",
|
||||
if s.current_uri.is_some() { 1u32 } else { 0u32 }
|
||||
);
|
||||
set!(
|
||||
&mut data,
|
||||
"TrackDuration",
|
||||
s.duration.clone().unwrap_or_else(|| "00:00:00".to_string())
|
||||
);
|
||||
set!(
|
||||
&mut data,
|
||||
"TrackURI",
|
||||
s.current_uri.clone().unwrap_or_default()
|
||||
);
|
||||
set!(
|
||||
&mut data,
|
||||
"TrackMetaData",
|
||||
s.current_metadata.clone().unwrap_or_default()
|
||||
);
|
||||
set!(
|
||||
&mut data,
|
||||
"RelTime",
|
||||
s.position.clone().unwrap_or_else(|| "00:00:00".to_string())
|
||||
);
|
||||
set!(
|
||||
&mut data,
|
||||
"AbsTime",
|
||||
s.position.clone().unwrap_or_else(|| "00:00:00".to_string())
|
||||
);
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(captures(state) |mut data| {
|
||||
let s = state.read();
|
||||
set!(&mut data, "Track", if s.current_uri.is_some() { 1u32 } else { 0u32 });
|
||||
set!(&mut data, "TrackDuration", s.duration.clone().unwrap_or_else(|| "00:00:00".to_string()));
|
||||
set!(&mut data, "TrackURI", s.current_uri.clone().unwrap_or_default());
|
||||
set!(&mut data, "TrackMetaData", s.current_metadata.clone().unwrap_or_default());
|
||||
set!(&mut data, "RelTime", s.position.clone().unwrap_or_else(|| "00:00:00".to_string()));
|
||||
set!(&mut data, "AbsTime", s.position.clone().unwrap_or_else(|| "00:00:00".to_string()));
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "GetTransportInfo" - retourne l'état du transport
|
||||
pub fn get_transport_info_handler(state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
let mut data = data;
|
||||
let s = state.read();
|
||||
tracing::info!("[WebRenderer] GetTransportInfo: state={:?}", s.playback_state);
|
||||
let transport_state = match s.playback_state {
|
||||
PlaybackState::Stopped => "STOPPED",
|
||||
PlaybackState::Playing => "PLAYING",
|
||||
PlaybackState::Paused => "PAUSED_PLAYBACK",
|
||||
PlaybackState::Transitioning => "TRANSITIONING",
|
||||
};
|
||||
set!(&mut data, "CurrentTransportState", transport_state.to_string());
|
||||
set!(&mut data, "CurrentTransportStatus", "OK".to_string());
|
||||
set!(&mut data, "CurrentSpeed", "1".to_string());
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(captures(state) |mut data| {
|
||||
let s = state.read();
|
||||
tracing::info!("[WebRenderer] GetTransportInfo: state={:?}", s.playback_state);
|
||||
let transport_state = match s.playback_state {
|
||||
PlaybackState::Stopped => "STOPPED",
|
||||
PlaybackState::Playing => "PLAYING",
|
||||
PlaybackState::Paused => "PAUSED_PLAYBACK",
|
||||
PlaybackState::Transitioning => "TRANSITIONING",
|
||||
};
|
||||
set!(&mut data, "CurrentTransportState", transport_state.to_string());
|
||||
set!(&mut data, "CurrentTransportStatus", "OK".to_string());
|
||||
set!(&mut data, "CurrentSpeed", "1".to_string());
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "GetMediaInfo" - retourne les infos du média
|
||||
pub fn get_media_info_handler(state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
let mut data = data;
|
||||
let s = state.read();
|
||||
set!(
|
||||
&mut data,
|
||||
"NrTracks",
|
||||
if s.current_uri.is_some() { 1u32 } else { 0u32 }
|
||||
);
|
||||
set!(&mut data, "CurrentURI", s.current_uri.clone().unwrap_or_default());
|
||||
set!(&mut data, "CurrentURIMetaData", s.current_metadata.clone().unwrap_or_default());
|
||||
set!(&mut data, "NextURI", s.next_uri.clone().unwrap_or_default());
|
||||
set!(&mut data, "NextURIMetaData", s.next_metadata.clone().unwrap_or_default());
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(captures(state) |mut data| {
|
||||
let s = state.read();
|
||||
set!(&mut data, "NrTracks", if s.current_uri.is_some() { 1u32 } else { 0u32 });
|
||||
set!(&mut data, "CurrentURI", s.current_uri.clone().unwrap_or_default());
|
||||
set!(&mut data, "CurrentURIMetaData", s.current_metadata.clone().unwrap_or_default());
|
||||
set!(&mut data, "NextURI", s.next_uri.clone().unwrap_or_default());
|
||||
set!(&mut data, "NextURIMetaData", s.next_metadata.clone().unwrap_or_default());
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
// ─── RenderingControl Handlers ──────────────────────────────────────────────
|
||||
// ─── ConnectionManager ─────────────────────────────────────────────────────────
|
||||
|
||||
/// Handler pour l'action UPnP "SetVolume" - définit le volume
|
||||
pub fn set_volume_handler(_pipeline: PipelineHandle, state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
let volume: u16 = get!(&data, "DesiredVolume", u16);
|
||||
state.write().volume = volume;
|
||||
Ok(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "GetVolume" - retourne le volume actuel
|
||||
pub fn get_volume_handler(state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
let mut data = data;
|
||||
let volume = state.read().volume;
|
||||
set!(&mut data, "CurrentVolume", volume);
|
||||
Ok(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "SetMute" - définit le mute
|
||||
pub fn set_mute_handler(_pipeline: PipelineHandle, state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
let mute: bool = get!(&data, "DesiredMute", bool);
|
||||
state.write().mute = mute;
|
||||
Ok(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler pour l'action UPnP "GetMute" - retourne l'état mute
|
||||
pub fn get_mute_handler(state: SharedState) -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
let mut data = data;
|
||||
let mute = state.read().mute;
|
||||
set!(&mut data, "CurrentMute", mute);
|
||||
Ok(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// ─── ConnectionManager Handlers ─────────────────────────────────────────────
|
||||
|
||||
/// Handler pour l'action UPnP "GetProtocolInfo" - retourne les protocoles supportés
|
||||
pub fn get_protocol_info_handler() -> ActionHandler {
|
||||
Arc::new(move |data: ActionData| -> ActionFuture {
|
||||
Box::pin(async move {
|
||||
let mut data = data;
|
||||
set!(&mut data, "Source", String::new());
|
||||
set!(
|
||||
&mut data,
|
||||
"Sink",
|
||||
"http-get:*:audio/flac:*,http-get:*:audio/x-flac:*".to_string()
|
||||
);
|
||||
Ok(data)
|
||||
})
|
||||
action_handler!(|mut data| {
|
||||
set!(&mut data, "Source", String::new());
|
||||
set!(&mut data, "Sink", "http-get:*:audio/flac:*,http-get:*:audio/x-flac:*".to_string());
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
// ─── RenderingControl ──────────────────────────────────────────────────────────
|
||||
|
||||
pub fn set_volume_handler(state: SharedState) -> ActionHandler {
|
||||
action_handler!(captures(state) |mut data| {
|
||||
let volume: u16 = get!(&data, "DesiredVolume", u16);
|
||||
state.write().volume = volume;
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_volume_handler(state: SharedState) -> ActionHandler {
|
||||
action_handler!(captures(state) |mut data| {
|
||||
let volume = state.read().volume;
|
||||
set!(&mut data, "CurrentVolume", volume);
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_mute_handler(state: SharedState) -> ActionHandler {
|
||||
action_handler!(captures(state) |mut data| {
|
||||
let mute: bool = get!(&data, "DesiredMute", bool);
|
||||
state.write().mute = mute;
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_mute_handler(state: SharedState) -> ActionHandler {
|
||||
action_handler!(captures(state) |mut data| {
|
||||
let mute = state.read().mute;
|
||||
set!(&mut data, "CurrentMute", mute);
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ impl WebRendererFactory {
|
||||
state: SharedState,
|
||||
) -> Result<Device, FactoryError> {
|
||||
let avtransport = Self::build_avtransport(pipeline.clone(), state.clone())?;
|
||||
let renderingcontrol = Self::build_renderingcontrol(pipeline.clone(), state.clone())?;
|
||||
let renderingcontrol = Self::build_renderingcontrol(state.clone())?;
|
||||
let connectionmanager = Self::build_connectionmanager()?;
|
||||
|
||||
let short_name = extract_browser_name(browser_ua);
|
||||
@@ -147,10 +147,6 @@ impl WebRendererFactory {
|
||||
state: SharedState,
|
||||
) -> Result<Service, FactoryError> {
|
||||
let mut svc = Service::new("AVTransport".to_string());
|
||||
let add_var = |svc: &mut Service, var: &Arc<pmoupnp::state_variables::StateVariable>| {
|
||||
svc.add_variable(Arc::clone(var))
|
||||
.map_err(|e| FactoryError::VariableError(e.to_string()))
|
||||
};
|
||||
|
||||
// Ajouter toutes les variables d'état
|
||||
add_var(&mut svc, &AVT_INSTANCE_ID)?;
|
||||
@@ -176,11 +172,6 @@ impl WebRendererFactory {
|
||||
add_var(&mut svc, &TRANSPORTSTATE)?;
|
||||
add_var(&mut svc, &TRANSPORTSTATUS)?;
|
||||
|
||||
let add_action = |svc: &mut Service, action: Arc<Action>| {
|
||||
svc.add_action(action)
|
||||
.map_err(|e| FactoryError::ActionError(e.to_string()))
|
||||
};
|
||||
|
||||
// Play
|
||||
let mut play = Action::new("Play".to_string());
|
||||
add_arg_in(&mut play, "InstanceID", &AVT_INSTANCE_ID)?;
|
||||
@@ -304,31 +295,21 @@ impl WebRendererFactory {
|
||||
Ok(svc)
|
||||
}
|
||||
|
||||
/// Construit le service RenderingControl avec les handlers pipeline
|
||||
fn build_renderingcontrol(
|
||||
pipeline: PipelineHandle,
|
||||
state: SharedState,
|
||||
) -> Result<Service, FactoryError> {
|
||||
/// Construit le service RenderingControl
|
||||
fn build_renderingcontrol(state: SharedState) -> Result<Service, FactoryError> {
|
||||
let mut svc = Service::new("RenderingControl".to_string());
|
||||
|
||||
svc.add_variable(Arc::clone(&RC_INSTANCE_ID))
|
||||
.map_err(|e| FactoryError::VariableError(e.to_string()))?;
|
||||
svc.add_variable(Arc::clone(&A_ARG_TYPE_CHANNEL))
|
||||
.map_err(|e| FactoryError::VariableError(e.to_string()))?;
|
||||
svc.add_variable(Arc::clone(&VOLUME))
|
||||
.map_err(|e| FactoryError::VariableError(e.to_string()))?;
|
||||
svc.add_variable(Arc::clone(&MUTE))
|
||||
.map_err(|e| FactoryError::VariableError(e.to_string()))?;
|
||||
add_var(&mut svc, &RC_INSTANCE_ID)?;
|
||||
add_var(&mut svc, &A_ARG_TYPE_CHANNEL)?;
|
||||
add_var(&mut svc, &VOLUME)?;
|
||||
add_var(&mut svc, &MUTE)?;
|
||||
|
||||
// SetVolume
|
||||
let mut set_vol = Action::new("SetVolume".to_string());
|
||||
add_arg_in(&mut set_vol, "InstanceID", &RC_INSTANCE_ID)?;
|
||||
add_arg_in(&mut set_vol, "Channel", &A_ARG_TYPE_CHANNEL)?;
|
||||
add_arg_in(&mut set_vol, "DesiredVolume", &VOLUME)?;
|
||||
set_vol.set_handler(handlers::set_volume_handler(
|
||||
pipeline.clone(),
|
||||
state.clone(),
|
||||
));
|
||||
set_vol.set_handler(handlers::set_volume_handler(state.clone()));
|
||||
add_action(&mut svc, Arc::new(set_vol))?;
|
||||
|
||||
// GetVolume
|
||||
@@ -345,7 +326,7 @@ impl WebRendererFactory {
|
||||
add_arg_in(&mut set_mute, "InstanceID", &RC_INSTANCE_ID)?;
|
||||
add_arg_in(&mut set_mute, "Channel", &A_ARG_TYPE_CHANNEL)?;
|
||||
add_arg_in(&mut set_mute, "DesiredMute", &MUTE)?;
|
||||
set_mute.set_handler(handlers::set_mute_handler(pipeline.clone(), state.clone()));
|
||||
set_mute.set_handler(handlers::set_mute_handler(state.clone()));
|
||||
add_action(&mut svc, Arc::new(set_mute))?;
|
||||
|
||||
// GetMute
|
||||
@@ -355,8 +336,7 @@ impl WebRendererFactory {
|
||||
add_arg_out(&mut get_mute, "CurrentMute", &MUTE)?;
|
||||
get_mute.set_stateful(false);
|
||||
get_mute.set_handler(handlers::get_mute_handler(state.clone()));
|
||||
svc.add_action(Arc::new(get_mute))
|
||||
.map_err(|e| FactoryError::ActionError(format!("{:?}", e)))?;
|
||||
add_action(&mut svc, Arc::new(get_mute))?;
|
||||
|
||||
Ok(svc)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user