use crate::{Position3D, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{Duration, Instant};
pub trait VisualDisplay: Send + Sync {
fn render_effect(&mut self, effect: &VisualEffect) -> Result<()>;
fn clear_all(&mut self) -> Result<()>;
fn update(&mut self) -> Result<()>;
fn is_ready(&self) -> bool;
fn capabilities(&self) -> VisualDisplayCapabilities;
fn display_id(&self) -> String;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VisualEffect {
pub id: String,
pub name: String,
pub elements: Vec<VisualElement>,
pub duration: Duration,
pub looping: bool,
pub priority: u8,
pub position: Position3D,
pub audio_source_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VisualElement {
pub start_time: Duration,
pub duration: Duration,
pub element_type: VisualElementType,
pub color: ColorRGBA,
pub intensity: f32,
pub size: f32,
pub animation: Option<AnimationParams>,
pub distance_attenuation: f32,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum VisualElementType {
PointLight,
DirectionalLight,
ParticleEffect,
Shape(ShapeType),
Text,
ProgressBar,
Waveform,
Spectrum,
Custom(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ShapeType {
Sphere,
Cube,
Cylinder,
Cone,
Ring,
Arrow,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct ColorRGBA {
pub r: f32,
pub g: f32,
pub b: f32,
pub a: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnimationParams {
pub animation_type: AnimationType,
pub speed: f32,
pub amplitude: f32,
pub phase: f32,
pub easing: EasingFunction,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum AnimationType {
Static,
Pulse,
Fade,
Rotate,
Scale,
Oscillate,
Spiral,
Custom(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum EasingFunction {
Linear,
EaseIn,
EaseOut,
EaseInOut,
Bounce,
Elastic,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VisualDisplayCapabilities {
pub max_concurrent_effects: usize,
pub supported_elements: Vec<VisualElementType>,
pub color_depth: u8,
pub refresh_rate: f32,
pub spatial_support: bool,
pub animation_support: bool,
pub alpha_support: bool,
pub resolution: (u32, u32),
pub field_of_view: Option<f32>,
pub features: HashMap<String, String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DirectionZone {
Front,
Left,
Back,
Right,
Above,
Below,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VisualAudioMetrics {
pub processing_latency: f32,
pub sync_accuracy: f32,
pub active_effects: usize,
pub frame_rate: f32,
pub gpu_utilization: f32,
pub cache_hit_rate: f32,
pub user_satisfaction: f32,
pub resource_usage: VisualResourceUsage,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VisualResourceUsage {
pub cpu_usage: f32,
pub gpu_memory_usage: f32,
pub system_memory_usage: f32,
pub effect_library_size: usize,
pub active_displays: usize,
pub render_queue_size: usize,
}
#[derive(Debug)]
pub(crate) struct VisualEvent {
pub(crate) source_id: String,
pub(crate) event_type: VisualEventType,
pub(crate) intensity: f32,
pub(crate) color_hint: Option<ColorRGBA>,
pub(crate) timestamp: Instant,
}
#[derive(Debug)]
pub(crate) struct SpatialVisualEvent {
pub(crate) base_event: VisualEvent,
pub(crate) position: Position3D,
pub(crate) distance: f32,
pub(crate) attenuation: f32,
pub(crate) direction_zone: DirectionZone,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum VisualEventType {
FrequencyBand(FrequencyBand),
Onset,
Beat,
Downbeat,
SpectralChange,
Silence,
Custom(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum FrequencyBand {
Low,
Mid,
High,
}
impl Default for VisualAudioMetrics {
fn default() -> Self {
Self {
processing_latency: 0.0,
sync_accuracy: 0.0,
active_effects: 0,
frame_rate: 0.0,
gpu_utilization: 0.0,
cache_hit_rate: 0.0,
user_satisfaction: 5.0,
resource_usage: VisualResourceUsage::default(),
}
}
}
impl Default for VisualResourceUsage {
fn default() -> Self {
Self {
cpu_usage: 0.0,
gpu_memory_usage: 0.0,
system_memory_usage: 0.0,
effect_library_size: 0,
active_displays: 0,
render_queue_size: 0,
}
}
}