amélioration de la webapp

This commit is contained in:
2025-10-19 13:42:29 +02:00
parent 756ae7f82c
commit 208fe8be76
179 changed files with 2426 additions and 1685 deletions

View File

@@ -7,10 +7,10 @@ use std::sync::RwLock;
use xmltree::Element;
use crate::{
object_trait::{UpnpInstance, UpnpObject},
state_variables::{StateVarInstance, StateVariable, UpnpVariable},
variable_types::{StateValue, StateValueError, UpnpVarType},
UpnpObjectType, UpnpTyped, UpnpTypedInstance
UpnpObjectType, UpnpTyped, UpnpTypedInstance,
object_trait::{UpnpInstance, UpnpObject},
state_variables::{StateVarInstance, StateVariable, UpnpVariable},
variable_types::{StateValue, StateValueError, UpnpVarType},
};
impl UpnpVariable for StateVarInstance {
@@ -49,7 +49,6 @@ impl UpnpInstance for StateVarInstance {
reflexive_cache: RwLock::new(None),
}
}
}
impl UpnpTyped for StateVarInstance {
@@ -59,7 +58,6 @@ impl UpnpTyped for StateVarInstance {
}
impl UpnpTypedInstance for StateVarInstance {
fn get_model(&self) -> &Self::Model {
&self.model
}
@@ -122,7 +120,7 @@ impl StateVarInstance {
// Validation du type
if self.as_state_var_type() != new_value.as_state_var_type() {
return Err(StateValueError::TypeError(
"Value type mismatch".to_string()
"Value type mismatch".to_string(),
));
}
@@ -191,7 +189,9 @@ impl StateVarInstance {
/// let reflected = var.reflexive_value();
/// // reflected peut maintenant être inspecté avec l'API Reflect
/// ```
pub fn reflexive_value(&self) -> Result<Arc<dyn Reflect>, crate::state_variables::StateVariableError> {
pub fn reflexive_value(
&self,
) -> Result<Arc<dyn Reflect>, crate::state_variables::StateVariableError> {
// Vérifier si on a un cache valide
{
let cache = self.reflexive_cache.read().unwrap();
@@ -256,7 +256,9 @@ impl StateVarInstance {
Err(e) => {
tracing::warn!(
"Failed to parse value '{}' for variable '{}': {:?}, using raw string",
s, self.get_name(), e
s,
self.get_name(),
e
);
}
}
@@ -285,7 +287,10 @@ impl StateVarInstance {
/// - La conversion Reflect → StateValue échoue
/// - Le marshalling échoue
/// - La mise à jour de la valeur échoue
pub async fn set_reflect_value(&self, reflect_value: Box<dyn Reflect>) -> Result<(), StateValueError> {
pub async fn set_reflect_value(
&self,
reflect_value: Box<dyn Reflect>,
) -> Result<(), StateValueError> {
use crate::variable_types::StateVarType;
// Convertir Reflect → StateValue
@@ -297,19 +302,18 @@ impl StateVarInstance {
Ok(temp_value) => {
// Utiliser le marshal pour obtenir la String marshallée
match marshal(&temp_value) {
Ok(marshalled_string) => {
StateValue::String(marshalled_string)
},
Ok(marshalled_string) => StateValue::String(marshalled_string),
Err(e) => {
tracing::warn!(
"Failed to marshal value for variable '{}': {:?}, using standard conversion",
self.get_name(), e
self.get_name(),
e
);
// Fallback
temp_value
}
}
},
}
Err(e) => return Err(e),
}
} else {

View File

@@ -1,15 +1,12 @@
mod errors;
mod instance_methods;
mod macros;
mod variable_methods;
mod var_set_methods;
mod var_inst_set_methods;
mod var_set_methods;
mod variable_methods;
mod variable_trait;
use std::{
collections::HashMap,
sync::Arc,
};
use std::{collections::HashMap, sync::Arc};
pub use crate::state_variables::variable_trait::UpnpVariable;
use bevy_reflect::Reflect;
@@ -18,9 +15,9 @@ pub use errors::StateVariableError;
use std::sync::RwLock;
use crate::{
value_ranges::ValueRange,
variable_types::{StateValue, StateVarType},
UpnpObjectSet, UpnpObjectType,
value_ranges::ValueRange,
variable_types::{StateValue, StateVarType},
};
/// Type pour les fonctions de condition d'événement
@@ -65,4 +62,3 @@ pub struct StateVarInstance {
}
pub type StateVarInstanceSet = UpnpObjectSet<StateVarInstance>;

View File

@@ -3,14 +3,17 @@ use std::collections::HashMap;
use std::sync::RwLock;
use xmltree::{Element, XMLNode};
use crate::{state_variables::{StateVarInstanceSet, StateVariableSet}, UpnpObject};
use crate::{
UpnpObject,
state_variables::{StateVarInstanceSet, StateVariableSet},
};
use crate::UpnpInstance;
impl UpnpObject for StateVarInstanceSet {
fn to_xml_element(&self) -> Element {
let mut elem = Element::new("serviceStateTable");
for state_var in self.all() {
let state_var_elem = state_var.to_xml_element(); // retourne un <stateVariable> complet
elem.children.push(XMLNode::Element(state_var_elem));
@@ -24,10 +27,8 @@ impl UpnpInstance for StateVarInstanceSet {
type Model = StateVariableSet;
fn new(_: &StateVariableSet) -> Self {
Self { objects: RwLock::new(HashMap::new()) }
Self {
objects: RwLock::new(HashMap::new()),
}
}
}

View File

@@ -1,13 +1,15 @@
use xmltree::{Element, XMLNode};
use crate::{object_trait::UpnpModel, state_variables::{StateVarInstanceSet, StateVariableSet}, UpnpObject};
use crate::{
UpnpObject,
object_trait::UpnpModel,
state_variables::{StateVarInstanceSet, StateVariableSet},
};
impl UpnpObject for StateVariableSet {
fn to_xml_element(&self) -> Element {
let mut elem = Element::new("serviceStateTable");
for state_var in self.all() {
let state_var_elem = state_var.to_xml_element(); // retourne un <stateVariable> complet
elem.children.push(XMLNode::Element(state_var_elem));
@@ -15,11 +17,8 @@ impl UpnpObject for StateVariableSet {
elem
}
}
impl UpnpModel for StateVariableSet {
type Instance = StateVarInstanceSet;
}

View File

@@ -1,8 +1,4 @@
use std::{
collections::HashMap,
fmt,
sync::Arc,
};
use std::{collections::HashMap, fmt, sync::Arc};
use std::sync::RwLock;
use xmltree::{Element, XMLNode};
@@ -112,17 +108,13 @@ impl Clone for StateVariable {
// clone safe des structures protégées par RwLock en prenant un read lock
let event_conditions_clone = {
// si le lock est "poisoned" on panic - tu peux adapter la gestion si tu veux
let guard = self
.event_conditions
.read().unwrap();
let guard = self.event_conditions.read().unwrap();
// nécessite que Key: Clone, Value: Clone
Arc::new(RwLock::new(guard.clone()))
};
let allowed_values_clone = {
let guard = self
.allowed_values
.read().unwrap();
let guard = self.allowed_values.read().unwrap();
Arc::new(RwLock::new(guard.clone()))
};
@@ -154,20 +146,14 @@ impl fmt::Debug for StateVariable {
.field("modifiable", &self.modifiable)
.field(
"event_conditions",
&format_args!(
"len={}",
self.event_conditions.read().unwrap().len()
),
&format_args!("len={}", self.event_conditions.read().unwrap().len()),
)
.field("description", &self.description)
.field("default_value", &self.default_value)
.field("value_range", &self.value_range)
.field(
"allowed_values",
&format_args!(
"len={}",
self.allowed_values.read().unwrap().len()
),
&format_args!("len={}", self.allowed_values.read().unwrap().len()),
)
.field("send_events", &self.send_events)
.field(
@@ -332,9 +318,7 @@ impl StateVariable {
}
pub fn extend_allowed_values(&mut self, values: &[StateValue]) -> Result<(), StateValueError> {
let mut av = self
.allowed_values
.write().unwrap();
let mut av = self.allowed_values.write().unwrap();
for v in values {
if self.as_state_var_type() == v.as_state_var_type() {
@@ -350,9 +334,7 @@ impl StateVariable {
}
pub fn push_allowed_value(&mut self, value: &StateValue) -> Result<(), StateValueError> {
let mut av = self
.allowed_values
.write().unwrap();
let mut av = self.allowed_values.write().unwrap();
if self.as_state_var_type() == value.as_state_var_type() {
av.push(value.clone());

View File

@@ -216,9 +216,7 @@ pub trait UpnpVariable {
///
/// Retourne `false` si le lock est empoisonné (poisoned).
fn has_allowed_values(&self) -> bool {
let guard = self.get_definition()
.allowed_values
.read().unwrap();
let guard = self.get_definition().allowed_values.read().unwrap();
!guard.is_empty()
}
@@ -250,9 +248,7 @@ pub trait UpnpVariable {
/// retourne `false`. Utilisez [`has_allowed_values`](Self::has_allowed_values)
/// pour distinguer "pas de liste" de "valeur non autorisée".
fn is_an_allowed_value(&self, value: &StateValue) -> bool {
let guard = self.get_definition()
.allowed_values
.read().unwrap();
let guard = self.get_definition().allowed_values.read().unwrap();
guard.contains(value)
}