use std::{collections::HashMap, sync::Arc};
use gled_midi::{HostEvent, native::NativeHost};
use gled_model::asset::scene::grid::GridLocation;
use kanal::{Receiver, unbounded};
use super::{
Engine, EngineConnector, RenderStats, applied_output::AppliedOutput, devices, midi_tools,
patch_layout::PatchLayout,
};
use crate::{
action::UiAction,
audio::{AudioPool, sound_data::SoundData},
input::external_control::ExternalControlState,
pipeline::extract_output::{ExtractOutput, OutputConfig, PreviewOutput},
runtime::{persistent_state::PersistentState, render_thread::RenderThread, timing::Timing},
storage::collections::Collections,
};
#[derive(Debug)]
pub(crate) struct EngineConfig {
pub(crate) adapter: wgpu::Adapter,
pub(crate) extract_output: ExtractOutput,
pub(crate) artnet_control_receiver: Receiver<Vec<u8>>,
pub(crate) preview_output: Receiver<PreviewOutput>,
pub(crate) network_stats: Receiver<(f64, f64)>,
pub(crate) temperature: Receiver<Option<f32>>,
pub(crate) midi: NativeHost,
pub(crate) midi_events: Receiver<HostEvent>,
pub(crate) audio_pool: AudioPool,
}
pub(crate) fn spawn(
config: EngineConfig,
actions: Receiver<UiAction>,
) -> anyhow::Result<EngineConnector> {
let timing = Timing::default();
let persistent_state = PersistentState::default();
let render_thread = RenderThread::spawn(
&config.adapter,
timing.link(),
config.extract_output,
persistent_state.fps_limit(),
)?;
let (input_sender, input_receiver) = unbounded();
let engine = Engine {
startup: true,
timing,
project: None,
project_id: None,
selected_scene_instance: GridLocation::default(),
effect_selection: Default::default(),
blackout: true,
blackout_hold: false,
midi_output_active: false,
actions,
inputs: input_receiver,
sessions: HashMap::new(),
collections: Collections::default(),
persistent_state,
output_config: OutputConfig::default(),
render_thread,
external_control_state: ExternalControlState::new(config.artnet_control_receiver),
audio_pool: config.audio_pool,
sound_data: SoundData::default(),
osc_handler: None,
osc_config: None,
applied_output: AppliedOutput::default(),
hovered_routing: None,
input_log: Arc::default(),
device_scan: devices::DeviceScan::default(),
pictures: Default::default(),
watched_triggers: HashMap::new(),
midi: midi_tools::MidiTools::new(config.midi, config.midi_events),
patch_layout: PatchLayout::default(),
render_stats: RenderStats::default(),
published_assets: (u64::MAX, Arc::default()),
preview_output: config.preview_output,
network_stats_receiver: config.network_stats,
network_stats: (0.0, 0.0),
temperature_receiver: config.temperature,
temperature: None,
host_name: gethostname::gethostname().to_string_lossy().into_owned(),
sound: Arc::default(),
ticks_since_sound: 0,
preview: None,
};
std::thread::Builder::new()
.name("gled:engine".to_string())
.spawn(move || engine.run())?;
Ok(EngineConnector {
inputs: input_sender,
next_id: Arc::default(),
})
}