Implemented creating device instances
This commit is contained in:
parent
c93bdab059
commit
50eb38aae1
3
Linux/.vscode/settings.json
vendored
3
Linux/.vscode/settings.json
vendored
@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"nixEnvSelector.nixFile": "${workspaceFolder}/shell.nix"
|
"nixEnvSelector.nixFile": "${workspaceFolder}/shell.nix",
|
||||||
|
"files.trimTrailingWhitespace": true
|
||||||
}
|
}
|
@ -1,17 +1,22 @@
|
|||||||
pub mod pipewire;
|
pub mod pipewire;
|
||||||
|
|
||||||
use crate::registry::MkRegistry;
|
use crate::registry::Registry;
|
||||||
use crate::registry::RegistryItem;
|
use crate::registry::RegistryItem;
|
||||||
use crate::util::unique_id::UniqueId;
|
use crate::util::unique_id::UniqueId;
|
||||||
|
|
||||||
|
|
||||||
pub struct MkAction
|
pub struct ActionRegistryItem
|
||||||
{
|
{
|
||||||
pub unique_id: UniqueId
|
pub unique_id: UniqueId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl RegistryItem for MkAction
|
pub trait Action
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl RegistryItem for ActionRegistryItem
|
||||||
{
|
{
|
||||||
fn unique_id(&self) -> UniqueId
|
fn unique_id(&self) -> UniqueId
|
||||||
{
|
{
|
||||||
@ -26,7 +31,7 @@ impl RegistryItem for MkAction
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn register(registry: &mut MkRegistry<MkAction>)
|
pub fn register(registry: &mut Registry<ActionRegistryItem>)
|
||||||
{
|
{
|
||||||
pipewire::register(registry);
|
pipewire::register(registry);
|
||||||
}
|
}
|
@ -1,13 +1,13 @@
|
|||||||
use crate::registry::MkRegistry;
|
use crate::registry::Registry;
|
||||||
use crate::util::unique_id::UniqueId;
|
use crate::util::unique_id::UniqueId;
|
||||||
use super::MkAction;
|
use super::ActionRegistryItem;
|
||||||
|
|
||||||
pub mod set_volume;
|
pub mod set_volume;
|
||||||
|
|
||||||
|
|
||||||
pub fn register(registry: &mut MkRegistry<MkAction>)
|
pub fn register(registry: &mut Registry<ActionRegistryItem>)
|
||||||
{
|
{
|
||||||
registry.register(MkAction
|
registry.register(ActionRegistryItem
|
||||||
{
|
{
|
||||||
unique_id: UniqueId::new("pipewire.set_volume")
|
unique_id: UniqueId::new("pipewire.set_volume")
|
||||||
});
|
});
|
||||||
|
@ -49,14 +49,19 @@ impl ConfigManager
|
|||||||
pub fn get_writer(&self, name: &ConfigName) -> Result<impl Write, Error>
|
pub fn get_writer(&self, name: &ConfigName) -> Result<impl Write, Error>
|
||||||
{
|
{
|
||||||
let path = Path::join(&self.root, name.as_str());
|
let path = Path::join(&self.root, name.as_str());
|
||||||
if !path.exists()
|
let parent = Path::parent(&path);
|
||||||
|
|
||||||
|
if let Some(parent) = parent
|
||||||
{
|
{
|
||||||
match std::fs::create_dir_all(path.clone())
|
if !parent.exists()
|
||||||
|
{
|
||||||
|
match std::fs::create_dir_all(parent)
|
||||||
{
|
{
|
||||||
Ok(_v) => (),
|
Ok(_v) => (),
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::fs::File::create(path)
|
std::fs::File::create(path)
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,58 @@
|
|||||||
use crate::registry::MkRegistry;
|
use emulatorwindow::EmulatorWindow;
|
||||||
|
use relm4::{component::Connector, ComponentController};
|
||||||
|
use relm4::Component;
|
||||||
|
use relm4::gtk::prelude::*;
|
||||||
|
|
||||||
|
use crate::registry::Registry;
|
||||||
use crate::util::unique_id::UniqueId;
|
use crate::util::unique_id::UniqueId;
|
||||||
use super::MkDevice;
|
use super::{Device, DeviceRegistryItem};
|
||||||
|
|
||||||
|
|
||||||
pub mod emulatorwindow;
|
pub mod emulatorwindow;
|
||||||
|
|
||||||
|
|
||||||
|
pub struct EmulatorWindowDevice
|
||||||
|
|
||||||
pub fn register(registry: &mut MkRegistry<MkDevice>)
|
|
||||||
{
|
{
|
||||||
registry.register(MkDevice {
|
window: Option<Connector<EmulatorWindow>>
|
||||||
unique_id: UniqueId::new("emulator")
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
let app = relm4::main_application();
|
|
||||||
let builder = EmulatorWindow::builder();
|
|
||||||
app.add_window(&builder.root);
|
|
||||||
|
|
||||||
builder.launch(()).detach_runtime();
|
impl EmulatorWindowDevice
|
||||||
*/
|
{
|
||||||
|
fn new() -> Self
|
||||||
|
{
|
||||||
|
EmulatorWindowDevice
|
||||||
|
{
|
||||||
|
window: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Device for EmulatorWindowDevice
|
||||||
|
{
|
||||||
|
fn activate(&mut self)
|
||||||
|
{
|
||||||
|
if self.window.is_some() { return }
|
||||||
|
|
||||||
|
let builder = EmulatorWindow::builder();
|
||||||
|
self.window = Some(builder.launch({}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn deactivate(&mut self)
|
||||||
|
{
|
||||||
|
let Some(window) = self.window.take() else { return };
|
||||||
|
|
||||||
|
window.widget().close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn register(registry: &mut Registry<DeviceRegistryItem>)
|
||||||
|
{
|
||||||
|
registry.register(DeviceRegistryItem {
|
||||||
|
unique_id: UniqueId::new("emulator"),
|
||||||
|
factory: || Box::new(EmulatorWindowDevice::new())
|
||||||
|
});
|
||||||
|
}
|
@ -2,18 +2,26 @@ pub mod emulator;
|
|||||||
pub mod serial_min;
|
pub mod serial_min;
|
||||||
|
|
||||||
|
|
||||||
use crate::registry::MkRegistry;
|
use crate::registry::Registry;
|
||||||
use crate::registry::RegistryItem;
|
use crate::registry::RegistryItem;
|
||||||
use crate::util::unique_id::UniqueId;
|
use crate::util::unique_id::UniqueId;
|
||||||
|
|
||||||
|
|
||||||
pub struct MkDevice
|
pub struct DeviceRegistryItem
|
||||||
{
|
{
|
||||||
pub unique_id: UniqueId
|
pub unique_id: UniqueId,
|
||||||
|
pub factory: fn() -> Box<dyn Device>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl RegistryItem for MkDevice
|
pub trait Device
|
||||||
|
{
|
||||||
|
fn activate(&mut self);
|
||||||
|
fn deactivate(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl RegistryItem for DeviceRegistryItem
|
||||||
{
|
{
|
||||||
fn unique_id(&self) -> UniqueId
|
fn unique_id(&self) -> UniqueId
|
||||||
{
|
{
|
||||||
@ -28,7 +36,7 @@ impl RegistryItem for MkDevice
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn register(registry: &mut MkRegistry<MkDevice>)
|
pub fn register(registry: &mut Registry<DeviceRegistryItem>)
|
||||||
{
|
{
|
||||||
emulator::register(registry);
|
emulator::register(registry);
|
||||||
serial_min::register(registry);
|
serial_min::register(registry);
|
||||||
|
@ -1,11 +1,33 @@
|
|||||||
use crate::registry::MkRegistry;
|
use crate::registry::Registry;
|
||||||
use crate::util::unique_id::UniqueId;
|
use crate::util::unique_id::UniqueId;
|
||||||
use super::MkDevice;
|
use super::{Device, DeviceRegistryItem};
|
||||||
|
|
||||||
|
|
||||||
pub fn register(registry: &mut MkRegistry<MkDevice>)
|
pub struct SerialMinDevice
|
||||||
{
|
{
|
||||||
registry.register(MkDevice {
|
|
||||||
unique_id: UniqueId::new("serial_min")
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Device for SerialMinDevice
|
||||||
|
{
|
||||||
|
fn activate(&mut self)
|
||||||
|
{
|
||||||
|
//todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn deactivate(&mut self)
|
||||||
|
{
|
||||||
|
//todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn register(registry: &mut Registry<DeviceRegistryItem>)
|
||||||
|
{
|
||||||
|
registry.register(DeviceRegistryItem {
|
||||||
|
unique_id: UniqueId::new("serial_min"),
|
||||||
|
factory: || Box::new(SerialMinDevice {})
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use env_logger::Env;
|
use env_logger::Env;
|
||||||
use mainwindow::MainWindowViewModel;
|
use mainwindow::MainWindowInit;
|
||||||
use orchestrator::Orchestrator;
|
use orchestrator::Orchestrator;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
|
|
||||||
@ -27,11 +28,13 @@ fn main()
|
|||||||
|
|
||||||
relm4_icons::initialize_icons();
|
relm4_icons::initialize_icons();
|
||||||
|
|
||||||
let orchestrator = Rc::new(Orchestrator::new());
|
let orchestrator = Rc::new(RefCell::new(Orchestrator::new()));
|
||||||
|
|
||||||
let app = RelmApp::new("com.github.mvrens.massiveknob");
|
let app = RelmApp::new("com.github.mvrens.massiveknob");
|
||||||
app.run::<mainwindow::MainWindow>(MainWindowViewModel
|
app.run::<mainwindow::MainWindow>(MainWindowInit
|
||||||
{
|
{
|
||||||
orchestrator: Rc::clone(&orchestrator)
|
orchestrator: Rc::clone(&orchestrator)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
orchestrator.borrow_mut().finalize();
|
||||||
}
|
}
|
@ -1,25 +1,31 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use gtk::glib::clone;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
|
|
||||||
use crate::{devices::MkDevice, orchestrator::Orchestrator, registry::RegistryItem, util::unique_id::UniqueId};
|
use crate::orchestrator::Orchestrator;
|
||||||
|
use crate::registry::RegistryItem;
|
||||||
|
use crate::util::unique_id::UniqueId;
|
||||||
|
|
||||||
pub struct MainWindow
|
pub struct MainWindow
|
||||||
{
|
{
|
||||||
|
orchestrator: Rc<RefCell<Orchestrator>>,
|
||||||
|
devices_sorted: Vec<SortedDevice>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct MainWindowViewModel
|
pub struct MainWindowInit
|
||||||
{
|
{
|
||||||
pub orchestrator: Rc<Orchestrator>
|
pub orchestrator: Rc<RefCell<Orchestrator>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl std::fmt::Debug for MainWindowViewModel
|
impl std::fmt::Debug for MainWindowInit
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
|
||||||
{
|
{
|
||||||
f.debug_struct("MainWindowViewModel")
|
f.debug_struct("MainWindowInit")
|
||||||
// Skip orchestrator
|
// Skip orchestrator
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
@ -29,25 +35,25 @@ impl std::fmt::Debug for MainWindowViewModel
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MainWindowMsg
|
pub enum MainWindowMsg
|
||||||
{
|
{
|
||||||
|
DeviceChanged(usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct MainWindowWidgets
|
pub struct MainWindowWidgets
|
||||||
{
|
{
|
||||||
device: MainWindowDeviceWidgets
|
_device: MainWindowDeviceWidgets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct MainWindowDeviceWidgets
|
pub struct MainWindowDeviceWidgets
|
||||||
{
|
{
|
||||||
devices_sorted: Vec<SortedDevice>,
|
_devices_combobox: gtk::ComboBoxText
|
||||||
devices_combobox: gtk::ComboBoxText
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl SimpleComponent for MainWindow
|
impl SimpleComponent for MainWindow
|
||||||
{
|
{
|
||||||
type Init = MainWindowViewModel;
|
type Init = MainWindowInit;
|
||||||
type Input = MainWindowMsg;
|
type Input = MainWindowMsg;
|
||||||
type Output = ();
|
type Output = ();
|
||||||
type Root = gtk::Window;
|
type Root = gtk::Window;
|
||||||
@ -65,12 +71,34 @@ impl SimpleComponent for MainWindow
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn init(data: Self::Init, window: Self::Root, _sender: ComponentSender<Self>, ) -> ComponentParts<Self>
|
fn init(data: Self::Init, window: Self::Root, sender: ComponentSender<Self>) -> ComponentParts<Self>
|
||||||
{
|
{
|
||||||
let orchestrator = data.orchestrator.as_ref();
|
{
|
||||||
|
let mut init_orchestrator = data.orchestrator.borrow_mut();
|
||||||
|
init_orchestrator.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
let model = MainWindow {};
|
|
||||||
let widgets = Self::init_ui(&window, &orchestrator);
|
let orchestrator = data.orchestrator.borrow();
|
||||||
|
|
||||||
|
let mut devices_sorted: Vec<SortedDevice> = orchestrator.devices()
|
||||||
|
.map(|device| SortedDevice
|
||||||
|
{
|
||||||
|
unique_id: device.unique_id(),
|
||||||
|
name: device.name()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
devices_sorted.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
|
||||||
|
|
||||||
|
|
||||||
|
let model = MainWindow
|
||||||
|
{
|
||||||
|
orchestrator: data.orchestrator.clone(),
|
||||||
|
devices_sorted
|
||||||
|
};
|
||||||
|
|
||||||
|
let widgets = MainWindowBuilder::new(&window, &model, &sender).build();
|
||||||
|
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
@ -80,22 +108,47 @@ impl SimpleComponent for MainWindow
|
|||||||
{
|
{
|
||||||
match msg
|
match msg
|
||||||
{
|
{
|
||||||
|
MainWindowMsg::DeviceChanged(index) =>
|
||||||
|
{
|
||||||
|
let mut orchestrator = self.orchestrator.borrow_mut();
|
||||||
|
let device = &self.devices_sorted[index];
|
||||||
|
|
||||||
|
orchestrator.set_current_device_id(device.unique_id.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct MainWindowBuilder<'a>
|
||||||
impl MainWindow
|
|
||||||
{
|
{
|
||||||
fn init_ui(window: >k::Window, orchestrator: &Orchestrator) -> MainWindowWidgets
|
window: &'a gtk::Window,
|
||||||
|
model: &'a MainWindow,
|
||||||
|
sender: &'a ComponentSender<MainWindow>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a> MainWindowBuilder<'a>
|
||||||
|
{
|
||||||
|
fn new(window: &'a gtk::Window, model: &'a MainWindow, sender: &'a ComponentSender<MainWindow>) -> Self
|
||||||
|
{
|
||||||
|
Self
|
||||||
|
{
|
||||||
|
window,
|
||||||
|
model,
|
||||||
|
sender
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn build(&self) -> MainWindowWidgets
|
||||||
{
|
{
|
||||||
let tabs = gtk::Notebook::builder().build();
|
let tabs = gtk::Notebook::builder().build();
|
||||||
window.set_child(Some(&tabs));
|
self.window.set_child(Some(&tabs));
|
||||||
|
|
||||||
MainWindowWidgets
|
MainWindowWidgets
|
||||||
{
|
{
|
||||||
device: Self::init_device_tab(&tabs, &orchestrator)
|
_device: self.init_device_tab(&tabs)
|
||||||
//Self::new_box_tab(&tabs, "mainwindow.tab.analoginputs");
|
//Self::new_box_tab(&tabs, "mainwindow.tab.analoginputs");
|
||||||
//Self::new_box_tab(&tabs, "mainwindow.tab.digitalinputs");
|
//Self::new_box_tab(&tabs, "mainwindow.tab.digitalinputs");
|
||||||
//Self::add_box_tab(&tabs, "mainwindow.tab.analogoutputs");
|
//Self::add_box_tab(&tabs, "mainwindow.tab.analogoutputs");
|
||||||
@ -104,8 +157,9 @@ impl MainWindow
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn init_device_tab(tabs: >k::Notebook, orchestrator: &Orchestrator) -> MainWindowDeviceWidgets
|
fn init_device_tab(&self, tabs: >k::Notebook) -> MainWindowDeviceWidgets
|
||||||
{
|
{
|
||||||
|
let sender = self.sender;
|
||||||
let tab = Self::new_box_tab(&tabs, "mainwindow.tab.device");
|
let tab = Self::new_box_tab(&tabs, "mainwindow.tab.device");
|
||||||
|
|
||||||
let label = gtk::Label::builder()
|
let label = gtk::Label::builder()
|
||||||
@ -120,27 +174,31 @@ impl MainWindow
|
|||||||
let devices_combobox = gtk::ComboBoxText::builder()
|
let devices_combobox = gtk::ComboBoxText::builder()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
let devices_combobox_cloned = devices_combobox.clone();
|
||||||
|
|
||||||
|
devices_combobox.connect_changed(clone!(
|
||||||
|
@strong sender => move |_|
|
||||||
|
{
|
||||||
|
if let Some(active_index) = devices_combobox_cloned.active()
|
||||||
|
{
|
||||||
|
if let Ok(active_index_usize) = usize::try_from(active_index)
|
||||||
|
{
|
||||||
|
sender.input(MainWindowMsg::DeviceChanged(active_index_usize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
tab.append(&devices_combobox);
|
tab.append(&devices_combobox);
|
||||||
|
|
||||||
|
|
||||||
let mut devices_sorted: Vec<SortedDevice> = orchestrator.devices()
|
let current_device_id = self.model.orchestrator.borrow().current_device_id();
|
||||||
.map(|device| SortedDevice
|
|
||||||
{
|
|
||||||
unique_id: device.unique_id(),
|
|
||||||
name: device.name()
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
devices_sorted.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
|
|
||||||
|
|
||||||
let current_device_id = orchestrator.current_device_id();
|
|
||||||
|
|
||||||
|
|
||||||
for (index, device) in devices_sorted.iter().enumerate()
|
for (index, device) in self.model.devices_sorted.iter().enumerate()
|
||||||
{
|
{
|
||||||
devices_combobox.append_text(device.name.as_str());
|
devices_combobox.append_text(device.name.as_str());
|
||||||
|
|
||||||
if let Some(device_id) = current_device_id
|
if let Some(device_id) = current_device_id.clone()
|
||||||
{
|
{
|
||||||
if device_id == device.unique_id
|
if device_id == device.unique_id
|
||||||
{
|
{
|
||||||
@ -152,8 +210,7 @@ impl MainWindow
|
|||||||
|
|
||||||
MainWindowDeviceWidgets
|
MainWindowDeviceWidgets
|
||||||
{
|
{
|
||||||
devices_sorted,
|
_devices_combobox: devices_combobox
|
||||||
devices_combobox
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::actions;
|
use crate::actions;
|
||||||
use crate::actions::MkAction;
|
use crate::actions::ActionRegistryItem;
|
||||||
use crate::config::json::JsonConfigManager;
|
use crate::config::json::JsonConfigManager;
|
||||||
use crate::config::{ConfigManager, ConfigName};
|
use crate::config::{ConfigManager, ConfigName};
|
||||||
use crate::devices;
|
use crate::devices::{self, Device};
|
||||||
use crate::devices::MkDevice;
|
use crate::devices::DeviceRegistryItem;
|
||||||
use crate::registry::MkRegistry;
|
use crate::registry::Registry;
|
||||||
use crate::util::unique_id::UniqueId;
|
use crate::util::unique_id::UniqueId;
|
||||||
|
|
||||||
|
|
||||||
@ -15,11 +15,14 @@ pub struct Orchestrator
|
|||||||
{
|
{
|
||||||
config_manager: ConfigManager,
|
config_manager: ConfigManager,
|
||||||
|
|
||||||
device_registry: MkRegistry<MkDevice>,
|
device_registry: Registry<DeviceRegistryItem>,
|
||||||
action_registry: MkRegistry<MkAction>,
|
action_registry: Registry<ActionRegistryItem>,
|
||||||
|
|
||||||
settings_name: ConfigName,
|
settings_name: ConfigName,
|
||||||
settings: settings::Settings
|
settings: settings::Settings,
|
||||||
|
|
||||||
|
|
||||||
|
current_device_instance: Option<Box<dyn Device>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -36,8 +39,8 @@ impl Orchestrator
|
|||||||
Some(v) => v
|
Some(v) => v
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut device_registry = MkRegistry::new();
|
let mut device_registry = Registry::new();
|
||||||
let mut action_registry = MkRegistry::new();
|
let mut action_registry = Registry::new();
|
||||||
|
|
||||||
devices::register(&mut device_registry);
|
devices::register(&mut device_registry);
|
||||||
actions::register(&mut action_registry);
|
actions::register(&mut action_registry);
|
||||||
@ -50,12 +53,27 @@ impl Orchestrator
|
|||||||
action_registry,
|
action_registry,
|
||||||
|
|
||||||
settings_name,
|
settings_name,
|
||||||
settings
|
settings,
|
||||||
|
|
||||||
|
|
||||||
|
current_device_instance: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn devices(&self) -> impl Iterator<Item = &MkDevice>
|
pub fn initialize(&mut self)
|
||||||
|
{
|
||||||
|
self.set_current_device(self.current_device_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn finalize(&mut self)
|
||||||
|
{
|
||||||
|
self.set_current_device(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn devices(&self) -> impl Iterator<Item = &DeviceRegistryItem>
|
||||||
{
|
{
|
||||||
self.device_registry.iter()
|
self.device_registry.iter()
|
||||||
}
|
}
|
||||||
@ -67,22 +85,23 @@ impl Orchestrator
|
|||||||
Some(UniqueId::new(device_id.as_str()))
|
Some(UniqueId::new(device_id.as_str()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_device(&self) -> Option<&MkDevice>
|
|
||||||
|
pub fn current_device(&self) -> Option<&DeviceRegistryItem>
|
||||||
{
|
{
|
||||||
let Some(device_id) = self.current_device_id() else { return None };
|
let Some(device_id) = self.current_device_id() else { return None };
|
||||||
self.device_registry.by_id(device_id)
|
self.device_registry.by_id(device_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn set_current_device_id(&mut self, id: &str)
|
pub fn set_current_device_id(&mut self, id: UniqueId)
|
||||||
{
|
{
|
||||||
let new_id = Some(String::from(id));
|
let new_id = Some(String::from(id.as_str()));
|
||||||
if new_id == self.settings.device_id { return; }
|
if new_id == self.settings.device_id { return; }
|
||||||
|
|
||||||
self.settings.device_id = new_id;
|
self.settings.device_id = new_id;
|
||||||
self.store_settings();
|
self.store_settings();
|
||||||
|
|
||||||
// TODO unload old device, activate new
|
self.set_current_device(Some(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -93,4 +112,36 @@ impl Orchestrator
|
|||||||
log::error!("Error writing settings: {e}");
|
log::error!("Error writing settings: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn set_current_device(&mut self, id: Option<UniqueId>)
|
||||||
|
{
|
||||||
|
let prev_device_instance;
|
||||||
|
let new_device = match id
|
||||||
|
{
|
||||||
|
None => None,
|
||||||
|
Some(v) => self.device_registry.by_id(v)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Replace the device instance
|
||||||
|
if let Some(new_device) = new_device
|
||||||
|
{
|
||||||
|
let mut new_device_instance = (new_device.factory)();
|
||||||
|
new_device_instance.activate();
|
||||||
|
|
||||||
|
prev_device_instance = self.current_device_instance.replace(new_device_instance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev_device_instance = self.current_device_instance.take();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Deactivate the previous instance
|
||||||
|
if let Some(mut prev_device_instance) = prev_device_instance
|
||||||
|
{
|
||||||
|
prev_device_instance.deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,14 +16,14 @@ pub trait RegistryItem
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub struct MkRegistry<T> where T: RegistryItem
|
pub struct Registry<T> where T: RegistryItem
|
||||||
{
|
{
|
||||||
items: HashMap<String, T>
|
items: HashMap<String, T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl<T> MkRegistry<T> where T: RegistryItem
|
impl<T> Registry<T> where T: RegistryItem
|
||||||
{
|
{
|
||||||
pub fn new() -> Self
|
pub fn new() -> Self
|
||||||
{
|
{
|
||||||
|
@ -4,8 +4,10 @@ use super::validated_string::{ValidatedString, ValidatedStringPattern};
|
|||||||
pub type UniqueId = ValidatedString<UniqueIdPattern>;
|
pub type UniqueId = ValidatedString<UniqueIdPattern>;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
pub struct UniqueIdPattern;
|
pub struct UniqueIdPattern;
|
||||||
|
|
||||||
|
|
||||||
impl ValidatedStringPattern for UniqueIdPattern
|
impl ValidatedStringPattern for UniqueIdPattern
|
||||||
{
|
{
|
||||||
fn pattern() -> &'static str { r"^[a-zA-Z0-9\.\-_]+$" }
|
fn pattern() -> &'static str { r"^[a-zA-Z0-9\.\-_]+$" }
|
||||||
|
Loading…
Reference in New Issue
Block a user