commit
This commit is contained in:
parent
1ced4381b8
commit
f44283160a
10 changed files with 181 additions and 138 deletions
|
@ -50,7 +50,6 @@ pub enum HandlerEvent {
|
|||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "command", rename_all = "kebab-case")]
|
||||
pub enum HandlerCommand {
|
||||
SetActivePages { key_page_id: String, knob_page_id: String },
|
||||
SetKeyStyle { path: KeyPath, value: Option<KeyStyle> },
|
||||
SetKnobStyle { path: KnobPath, value: Option<KnobStyle> },
|
||||
SetKnobValue { path: KnobPath, value: Option<f32> },
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::style::{KeyStyle, KnobStyle};
|
|||
#[derive(Debug)]
|
||||
pub struct Key {
|
||||
pub path: KeyPath,
|
||||
pub host_id: Box<str>,
|
||||
pub base_style: KeyStyle,
|
||||
pub style: Option<KeyStyle>,
|
||||
}
|
||||
|
@ -13,6 +14,7 @@ pub struct Key {
|
|||
#[derive(Debug)]
|
||||
pub struct Knob {
|
||||
pub path: KnobPath,
|
||||
pub host_id: Box<str>,
|
||||
pub base_style: KnobStyle,
|
||||
pub style: Option<KnobStyle>,
|
||||
pub value: Option<f32>,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use bytes::{BufMut, Bytes, BytesMut};
|
||||
use resvg::usvg::tiny_skia_path::PathBuilder;
|
||||
|
@ -18,10 +19,11 @@ pub struct GraphicsContext {
|
|||
pub icon_manager: IconManager,
|
||||
}
|
||||
|
||||
pub fn render_key(context: &GraphicsContext, key_size: IntSize, state: Option<&Key>) -> Bytes {
|
||||
pub fn render_key(context: &GraphicsContext, key_size: IntSize, active_remote_handler_host_ids: &HashSet<Box<str>>, state: Option<&Key>) -> Bytes {
|
||||
let mut pixmap = Pixmap::new(key_size.width(), key_size.height()).expect("constraints were already asserted by IntSize");
|
||||
|
||||
if let Some(state) = state {
|
||||
if active_remote_handler_host_ids.contains(&state.host_id) {
|
||||
let style = state.style.as_ref().map(|s| s.merge_over(&state.base_style));
|
||||
let style = style.as_ref().unwrap_or(&state.base_style);
|
||||
|
||||
|
@ -38,8 +40,9 @@ pub fn render_key(context: &GraphicsContext, key_size: IntSize, state: Option<&K
|
|||
}
|
||||
|
||||
if let Some(color) = style.border {
|
||||
let path =
|
||||
PathBuilder::from_rect(Rect::from_xywh(-1.0, -2.0, pixmap.width() as f32, pixmap.height() as f32).expect("width and height are not negative"));
|
||||
let path = PathBuilder::from_rect(
|
||||
Rect::from_xywh(-1.0, -2.0, pixmap.width() as f32, pixmap.height() as f32).expect("width and height are not negative"),
|
||||
);
|
||||
|
||||
let paint = Paint {
|
||||
shader: Shader::SolidColor(Color::from_rgba8(color.r, color.g, color.b, color.a)),
|
||||
|
@ -57,14 +60,16 @@ pub fn render_key(context: &GraphicsContext, key_size: IntSize, state: Option<&K
|
|||
pixmap.stroke_path(&path, &paint, &STROKE, Transform::identity(), None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
convert_pixels_to_rgb565(pixmap.pixels(), context.buffer_endianness).freeze()
|
||||
}
|
||||
|
||||
pub fn render_knob(context: &GraphicsContext, screen_size: IntSize, state: Option<&Knob>) -> Bytes {
|
||||
pub fn render_knob(context: &GraphicsContext, screen_size: IntSize, active_remote_handler_host_ids: &HashSet<Box<str>>, state: Option<&Knob>) -> Bytes {
|
||||
let mut pixmap = Pixmap::new(screen_size.width(), screen_size.height()).expect("constraints were already asserted by IntSize");
|
||||
|
||||
if let Some(state) = state {
|
||||
if active_remote_handler_host_ids.contains(&state.host_id) {
|
||||
let style = state.style.as_ref().map(|s| s.merge_over(&state.base_style));
|
||||
let style = style.as_ref().unwrap_or(&state.base_style);
|
||||
|
||||
|
@ -115,6 +120,7 @@ pub fn render_knob(context: &GraphicsContext, screen_size: IntSize, state: Optio
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
convert_pixels_to_rgb565(pixmap.pixels(), context.buffer_endianness).freeze()
|
||||
}
|
||||
|
|
|
@ -21,17 +21,25 @@ use crate::icons::IconManager;
|
|||
use crate::model::coordinator_config::Config;
|
||||
use crate::model::position::ButtonPosition;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum CoordinatorCommand {
|
||||
SetActivePages { key_page_id: String, knob_page_id: String },
|
||||
SetRemoteHostIsActive { host_id: Box<str>, is_active: bool },
|
||||
}
|
||||
|
||||
enum IoWork {
|
||||
DeviceEvent(LoupedeckEvent),
|
||||
Command(HandlerCommand),
|
||||
HandlerCommand(HandlerCommand),
|
||||
CoordinatorCommand(CoordinatorCommand),
|
||||
}
|
||||
|
||||
pub struct IoWorkerContext {
|
||||
config: Arc<Config>,
|
||||
device: LoupedeckDevice,
|
||||
commands_sender: flume::Sender<HandlerCommand>,
|
||||
coordinator_commands_sender: flume::Sender<CoordinatorCommand>,
|
||||
events_sender: broadcast::Sender<HandlerEvent>,
|
||||
graphics: GraphicsContext,
|
||||
state: State,
|
||||
}
|
||||
|
||||
impl IoWorkerContext {
|
||||
|
@ -39,52 +47,59 @@ impl IoWorkerContext {
|
|||
config_directory: &Path,
|
||||
config: Arc<Config>,
|
||||
device: LoupedeckDevice,
|
||||
commands_sender: flume::Sender<HandlerCommand>,
|
||||
coordinator_commands_sender: flume::Sender<CoordinatorCommand>,
|
||||
events_sender: broadcast::Sender<HandlerEvent>,
|
||||
) -> Self {
|
||||
let buffer_endianness = device.characteristics().key_grid.display.endianness;
|
||||
let label_renderer = RefCell::new(LabelRenderer::new(config.label_font_family.as_ref()));
|
||||
let dpi = device.characteristics().key_grid.display.dpi;
|
||||
let icon_packs = Arc::clone(&config.icon_packs);
|
||||
let state = State::create(&config);
|
||||
|
||||
IoWorkerContext {
|
||||
config,
|
||||
device,
|
||||
commands_sender,
|
||||
coordinator_commands_sender,
|
||||
events_sender,
|
||||
graphics: GraphicsContext {
|
||||
buffer_endianness,
|
||||
label_renderer,
|
||||
icon_manager: IconManager::new(config_directory.to_path_buf(), icon_packs, dpi),
|
||||
},
|
||||
state,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn do_io_work(context: IoWorkerContext, commands_receiver: flume::Receiver<HandlerCommand>) {
|
||||
let mut state = State::create(&context.config);
|
||||
pub fn do_io_work(
|
||||
mut context: IoWorkerContext,
|
||||
coordinator_commands_receiver: &flume::Receiver<CoordinatorCommand>,
|
||||
handler_commands_receiver: &flume::Receiver<HandlerCommand>,
|
||||
) {
|
||||
let device_events_receiver = context.device.events();
|
||||
|
||||
loop {
|
||||
let a = flume::Selector::new()
|
||||
let work = flume::Selector::new()
|
||||
.recv(&device_events_receiver, |e| {
|
||||
IoWork::DeviceEvent(e.expect("the device events channel is not closed by the other side"))
|
||||
})
|
||||
.recv(&commands_receiver, |c| IoWork::Command(c.unwrap()))
|
||||
.recv(coordinator_commands_receiver, |c| IoWork::CoordinatorCommand(c.unwrap()))
|
||||
.recv(handler_commands_receiver, |c| IoWork::HandlerCommand(c.unwrap()))
|
||||
.wait();
|
||||
|
||||
match a {
|
||||
match work {
|
||||
IoWork::DeviceEvent(event) => {
|
||||
if !handle_event(&context, &mut state, event) {
|
||||
if !handle_event(&mut context, event) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
IoWork::Command(command) => handle_command(&context, &mut state, command),
|
||||
IoWork::CoordinatorCommand(command) => handle_coordinator_command(&mut context, command),
|
||||
IoWork::HandlerCommand(command) => handle_handler_command(&mut context, command),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(context: &IoWorkerContext, state: &mut State, event: LoupedeckEvent) -> bool {
|
||||
fn handle_event(context: &mut IoWorkerContext, event: LoupedeckEvent) -> bool {
|
||||
log::trace!("Handling event: {:?}", &event);
|
||||
|
||||
let send_key_event = |path: KeyPath, event: KeyEvent| {
|
||||
|
@ -104,10 +119,10 @@ fn handle_event(context: &IoWorkerContext, state: &mut State, event: LoupedeckEv
|
|||
let button_config = &context.config.buttons[position];
|
||||
|
||||
context
|
||||
.commands_sender
|
||||
.send(HandlerCommand::SetActivePages {
|
||||
key_page_id: button_config.key_page.as_ref().unwrap_or(&state.active_key_page_id).clone(),
|
||||
knob_page_id: button_config.knob_page.as_ref().unwrap_or(&state.active_knob_page_id).clone(),
|
||||
.coordinator_commands_sender
|
||||
.send(CoordinatorCommand::SetActivePages {
|
||||
key_page_id: button_config.key_page.as_ref().unwrap_or(&context.state.active_key_page_id).clone(),
|
||||
knob_page_id: button_config.knob_page.as_ref().unwrap_or(&context.state.active_knob_page_id).clone(),
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
@ -125,7 +140,7 @@ fn handle_event(context: &IoWorkerContext, state: &mut State, event: LoupedeckEv
|
|||
};
|
||||
|
||||
let path = KeyPath {
|
||||
page_id: state.active_key_page_id.clone(),
|
||||
page_id: context.state.active_key_page_id.clone(),
|
||||
position,
|
||||
};
|
||||
|
||||
|
@ -137,10 +152,10 @@ fn handle_event(context: &IoWorkerContext, state: &mut State, event: LoupedeckEv
|
|||
.expect("the key index is valid because is was returned by get_key_at_global_coordinates");
|
||||
|
||||
let kind = if is_end {
|
||||
state.active_touch_ids.remove(&touch_id);
|
||||
context.state.active_touch_ids.remove(&touch_id);
|
||||
KeyTouchEventKind::End
|
||||
} else {
|
||||
let is_new = state.active_touch_ids.insert(touch_id);
|
||||
let is_new = context.state.active_touch_ids.insert(touch_id);
|
||||
if is_new {
|
||||
KeyTouchEventKind::Start
|
||||
} else {
|
||||
|
@ -170,7 +185,7 @@ fn handle_event(context: &IoWorkerContext, state: &mut State, event: LoupedeckEv
|
|||
|
||||
send_knob_event(
|
||||
KnobPath {
|
||||
page_id: state.active_knob_page_id.clone(),
|
||||
page_id: context.state.active_knob_page_id.clone(),
|
||||
position,
|
||||
},
|
||||
KnobEvent::Rotate {
|
||||
|
@ -186,7 +201,7 @@ fn handle_event(context: &IoWorkerContext, state: &mut State, event: LoupedeckEv
|
|||
|
||||
send_knob_event(
|
||||
KnobPath {
|
||||
page_id: state.active_knob_page_id.clone(),
|
||||
page_id: context.state.active_knob_page_id.clone(),
|
||||
position,
|
||||
},
|
||||
KnobEvent::Press,
|
||||
|
@ -198,46 +213,53 @@ fn handle_event(context: &IoWorkerContext, state: &mut State, event: LoupedeckEv
|
|||
true
|
||||
}
|
||||
|
||||
fn handle_command(context: &IoWorkerContext, state: &mut State, command: HandlerCommand) {
|
||||
log::trace!("Handling command: {:?}", &command);
|
||||
fn handle_coordinator_command(context: &mut IoWorkerContext, command: CoordinatorCommand) {
|
||||
log::trace!("Handling coordinator command: {:?}", &command);
|
||||
|
||||
match command {
|
||||
HandlerCommand::SetActivePages { key_page_id, knob_page_id } => {
|
||||
state.active_key_page_id = key_page_id;
|
||||
state.active_knob_page_id = knob_page_id;
|
||||
CoordinatorCommand::SetActivePages { key_page_id, knob_page_id } => {
|
||||
context.state.active_key_page_id = key_page_id;
|
||||
context.state.active_knob_page_id = knob_page_id;
|
||||
|
||||
for button in context.device.characteristics().available_buttons {
|
||||
context
|
||||
.device
|
||||
.set_button_color(button, get_correct_button_color(context, state, ButtonPosition::of(&button)))
|
||||
.set_button_color(button, get_correct_button_color(context, &context.state, ButtonPosition::of(&button)))
|
||||
.expect("the button is available for this device because that is literally what we are iterating over");
|
||||
}
|
||||
|
||||
let key_grid = &context.device.characteristics().key_grid;
|
||||
for index in 0..(key_grid.rows * key_grid.columns) {
|
||||
draw_key_at_index(context, state, index);
|
||||
redraw_visible_page(&context);
|
||||
}
|
||||
CoordinatorCommand::SetRemoteHostIsActive { host_id, is_active } => {
|
||||
if is_active {
|
||||
context.state.active_remote_handler_host_ids.insert(host_id);
|
||||
} else {
|
||||
context.state.active_remote_handler_host_ids.remove(&host_id);
|
||||
}
|
||||
|
||||
for position in KnobPosition::VARIANTS {
|
||||
draw_knob_at_position(context, state, *position);
|
||||
redraw_visible_page(&context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.device.refresh_display(&key_grid.display).unwrap();
|
||||
}
|
||||
fn handle_handler_command(context: &mut IoWorkerContext, command: HandlerCommand) {
|
||||
log::trace!("Handling handler command: {:?}", &command);
|
||||
|
||||
match command {
|
||||
HandlerCommand::SetKeyStyle { path, value } => {
|
||||
state.mutate_key_for_command("SetKeyStyle", &path, |k| {
|
||||
context.state.mutate_key_for_command("SetKeyStyle", &path, |k| {
|
||||
k.style = value;
|
||||
});
|
||||
|
||||
draw_key_at_path_if_visible(context, state, path);
|
||||
draw_key_at_path_if_visible(context, path);
|
||||
context.device.refresh_display(&context.device.characteristics().key_grid.display).unwrap();
|
||||
}
|
||||
HandlerCommand::SetKnobStyle { path, value } => {
|
||||
state.mutate_knob_for_command("SetKnobStyle", &path, |k| {
|
||||
context.state.mutate_knob_for_command("SetKnobStyle", &path, |k| {
|
||||
k.style = value;
|
||||
});
|
||||
|
||||
draw_knob_at_path_if_visible(context, state, path);
|
||||
draw_knob_at_path_if_visible(context, path);
|
||||
context.device.refresh_display(&context.device.characteristics().key_grid.display).unwrap();
|
||||
}
|
||||
HandlerCommand::SetKnobValue { path, value } => {
|
||||
|
@ -248,15 +270,28 @@ fn handle_command(context: &IoWorkerContext, state: &mut State, command: Handler
|
|||
}
|
||||
}
|
||||
|
||||
state.mutate_knob_for_command("SetKnobValue", &path, |k| {
|
||||
context.state.mutate_knob_for_command("SetKnobValue", &path, |k| {
|
||||
k.value = value;
|
||||
});
|
||||
|
||||
draw_knob_at_path_if_visible(context, state, path);
|
||||
draw_knob_at_path_if_visible(context, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn redraw_visible_page(context: &IoWorkerContext) {
|
||||
let key_grid = &context.device.characteristics().key_grid;
|
||||
for index in 0..(key_grid.rows * key_grid.columns) {
|
||||
draw_key_at_index(context, index);
|
||||
}
|
||||
|
||||
for position in KnobPosition::VARIANTS {
|
||||
draw_knob_at_position(context, *position);
|
||||
}
|
||||
|
||||
context.device.refresh_display(&key_grid.display).unwrap();
|
||||
}
|
||||
|
||||
// active -> config.active_button_color
|
||||
// no actions defined -> #000000
|
||||
// inactive -> config.inactive_button_color
|
||||
|
@ -306,6 +341,7 @@ fn draw_key(context: &IoWorkerContext, index: u8, key: Option<&Key>) {
|
|||
let buffer = render_key(
|
||||
&context.graphics,
|
||||
IntSize::from_wh(rect.w as u32, rect.h as u32).expect("rect.w and rect.h are not zero"),
|
||||
&context.state.active_remote_handler_host_ids,
|
||||
key,
|
||||
);
|
||||
context
|
||||
|
@ -314,23 +350,23 @@ fn draw_key(context: &IoWorkerContext, index: u8, key: Option<&Key>) {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
fn draw_key_at_index(context: &IoWorkerContext, state: &State, index: u8) {
|
||||
fn draw_key_at_index(context: &IoWorkerContext, index: u8) {
|
||||
let position = get_key_position_for_index(&context.device.characteristics().key_grid, index);
|
||||
|
||||
draw_key(context, index, state.active_key_page().keys_by_position.get(&position));
|
||||
draw_key(context, index, context.state.active_key_page().keys_by_position.get(&position));
|
||||
}
|
||||
|
||||
fn draw_key_at_position_if_visible(context: &IoWorkerContext, state: &State, position: KeyPosition) {
|
||||
fn draw_key_at_position_if_visible(context: &IoWorkerContext, position: KeyPosition) {
|
||||
let index = get_key_index_for_position(&context.device.characteristics().key_grid, position);
|
||||
|
||||
if let Some(index) = index {
|
||||
draw_key(context, index, state.active_key_page().keys_by_position.get(&position));
|
||||
draw_key(context, index, context.state.active_key_page().keys_by_position.get(&position));
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_key_at_path_if_visible(context: &IoWorkerContext, state: &State, path: KeyPath) {
|
||||
if state.active_key_page_id == path.page_id {
|
||||
draw_key_at_position_if_visible(context, state, path.position);
|
||||
fn draw_key_at_path_if_visible(context: &IoWorkerContext, path: KeyPath) {
|
||||
if context.state.active_key_page_id == path.page_id {
|
||||
draw_key_at_position_if_visible(context, path.position);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,6 +382,7 @@ fn draw_knob(context: &IoWorkerContext, position: KnobPosition, knob: Option<&Kn
|
|||
let buffer = render_knob(
|
||||
&context.graphics,
|
||||
IntSize::from_wh(rect.w as u32, rect.h as u32).expect("rect.w and rect.h are not zero."),
|
||||
&context.state.active_remote_handler_host_ids,
|
||||
knob,
|
||||
);
|
||||
context
|
||||
|
@ -355,13 +392,13 @@ fn draw_knob(context: &IoWorkerContext, position: KnobPosition, knob: Option<&Kn
|
|||
}
|
||||
}
|
||||
|
||||
fn draw_knob_at_position(context: &IoWorkerContext, state: &State, position: KnobPosition) {
|
||||
draw_knob(context, position, Some(&state.active_knob_page().knobs_by_position[position]));
|
||||
fn draw_knob_at_position(context: &IoWorkerContext, position: KnobPosition) {
|
||||
draw_knob(context, position, Some(&context.state.active_knob_page().knobs_by_position[position]));
|
||||
}
|
||||
|
||||
fn draw_knob_at_path_if_visible(context: &IoWorkerContext, state: &State, path: KnobPath) {
|
||||
if state.active_knob_page_id == path.page_id {
|
||||
draw_knob_at_position(context, state, path.position);
|
||||
fn draw_knob_at_path_if_visible(context: &IoWorkerContext, path: KnobPath) {
|
||||
if context.state.active_knob_page_id == path.page_id {
|
||||
draw_knob_at_position(context, path.position);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,11 @@ use deckster_shared::path::{KeyPath, KnobPath};
|
|||
use loupedeck_serial::commands::VibrationPattern;
|
||||
use loupedeck_serial::device::LoupedeckDevice;
|
||||
|
||||
use crate::coordinator::io_worker::{do_io_work, IoWorkerContext};
|
||||
use crate::coordinator::io_worker::{do_io_work, CoordinatorCommand, IoWorkerContext};
|
||||
use crate::coordinator::mqtt::start_mqtt_client;
|
||||
use crate::handler_runner;
|
||||
use crate::handler_runner::KeyOrKnobHandlerConfig;
|
||||
use crate::model::coordinator_config::Config;
|
||||
use crate::model::get_default_host_id;
|
||||
use crate::model::mqtt::HandlerHostsConfig;
|
||||
|
||||
mod graphics;
|
||||
|
@ -33,11 +32,12 @@ pub async fn start(config_directory: &Path, config: Config) -> Result<()> {
|
|||
let available_device = available_devices.first().wrap_err("No device connected.")?;
|
||||
log::info!("Found {} device(s).", available_devices.len());
|
||||
|
||||
let (commands_sender, commands_receiver) = flume::bounded::<HandlerCommand>(5);
|
||||
let (coordinator_commands_sender, coordinator_commands_receiver) = flume::bounded::<CoordinatorCommand>(5);
|
||||
let (handler_commands_sender, handler_commands_receiver) = flume::bounded::<HandlerCommand>(5);
|
||||
let events_sender = broadcast::Sender::<HandlerEvent>::new(5);
|
||||
|
||||
commands_sender
|
||||
.send(HandlerCommand::SetActivePages {
|
||||
coordinator_commands_sender
|
||||
.send(CoordinatorCommand::SetActivePages {
|
||||
knob_page_id: config.initial.knob_page.clone(),
|
||||
key_page_id: config.initial.key_page.clone(),
|
||||
})
|
||||
|
@ -91,16 +91,16 @@ pub async fn start(config_directory: &Path, config: Config) -> Result<()> {
|
|||
|
||||
if let Some(mqtt_config) = &config.mqtt {
|
||||
log::info!("Initializing MQTT client…");
|
||||
start_mqtt_client(mqtt_config, &handler_hosts_config, commands_sender.clone(), events_sender.subscribe()).await;
|
||||
start_mqtt_client(mqtt_config, &handler_hosts_config, handler_commands_sender.clone(), events_sender.subscribe()).await;
|
||||
}
|
||||
|
||||
log::info!("Initializing handler processes…");
|
||||
|
||||
handler_runner::start(
|
||||
get_default_host_id(),
|
||||
String::default().into_boxed_str(),
|
||||
&config_directory.join("handlers"),
|
||||
handler_hosts_config,
|
||||
commands_sender.clone(),
|
||||
handler_commands_sender.clone(),
|
||||
events_sender.subscribe(),
|
||||
)
|
||||
.await?;
|
||||
|
@ -112,12 +112,12 @@ pub async fn start(config_directory: &Path, config: Config) -> Result<()> {
|
|||
device.set_brightness(0.5);
|
||||
device.vibrate(VibrationPattern::RiseFall);
|
||||
|
||||
let io_worker_context = IoWorkerContext::create(config_directory, Arc::clone(&config), device, commands_sender.clone(), events_sender);
|
||||
let io_worker_context = IoWorkerContext::create(config_directory, Arc::clone(&config), device, coordinator_commands_sender, events_sender);
|
||||
|
||||
let io_worker_thread = thread::Builder::new()
|
||||
.name("deckster IO worker".to_owned())
|
||||
.spawn(move || {
|
||||
do_io_work(io_worker_context, commands_receiver);
|
||||
do_io_work(io_worker_context, &coordinator_commands_receiver, &handler_commands_receiver);
|
||||
})
|
||||
.wrap_err("Could not spawn the worker thread")?;
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ pub struct State {
|
|||
pub active_key_page_id: String,
|
||||
pub active_knob_page_id: String,
|
||||
pub active_touch_ids: HashSet<u8>,
|
||||
pub active_remote_handler_host_ids: HashSet<Box<str>>,
|
||||
pub key_pages_by_id: HashMap<String, KeyPage>,
|
||||
pub knob_pages_by_id: HashMap<String, KnobPage>,
|
||||
}
|
||||
|
@ -32,6 +33,7 @@ impl State {
|
|||
page_id: p.id.clone(),
|
||||
position: *position,
|
||||
},
|
||||
host_id: k.host.clone(),
|
||||
base_style: k.base_style.clone(),
|
||||
style: None,
|
||||
})
|
||||
|
@ -54,6 +56,7 @@ impl State {
|
|||
page_id: p.id.clone(),
|
||||
position,
|
||||
},
|
||||
host_id: knob_config.host.clone(),
|
||||
base_style: knob_config.base_style.clone(),
|
||||
style: None,
|
||||
value: None,
|
||||
|
@ -67,6 +70,7 @@ impl State {
|
|||
active_key_page_id: config.initial.key_page.clone(),
|
||||
active_knob_page_id: config.initial.knob_page.clone(),
|
||||
active_touch_ids: HashSet::new(),
|
||||
active_remote_handler_host_ids: HashSet::new(),
|
||||
key_pages_by_id,
|
||||
knob_pages_by_id,
|
||||
}
|
||||
|
|
|
@ -135,7 +135,6 @@ pub async fn start_mqtt_client(
|
|||
tokio::spawn(async move {
|
||||
while let Ok(command) = commands_receiver.recv_async().await {
|
||||
match command {
|
||||
HandlerCommand::SetActivePages { .. } => log::warn!("HandlerCommand::SetActivePages is not supported for remote handlers."),
|
||||
HandlerCommand::SetKeyStyle { path, value } => client
|
||||
.publish(
|
||||
format!("{topic_prefix}/keys/{path}/style"),
|
||||
|
|
|
@ -50,7 +50,7 @@ pub struct Key {
|
|||
#[serde(default, flatten)]
|
||||
pub base_style: KeyStyle,
|
||||
|
||||
#[serde(default = "super::get_default_host_id")]
|
||||
#[serde(default)]
|
||||
pub host: Box<str>,
|
||||
pub handler: Box<str>,
|
||||
pub config: Arc<toml::Table>,
|
||||
|
|
|
@ -24,7 +24,7 @@ pub struct Knob {
|
|||
#[serde(default, flatten)]
|
||||
pub base_style: KnobStyle,
|
||||
|
||||
#[serde(default = "super::get_default_host_id")]
|
||||
#[serde(default)]
|
||||
pub host: Box<str>,
|
||||
pub handler: Box<str>,
|
||||
pub config: Arc<toml::Table>,
|
||||
|
|
|
@ -5,7 +5,3 @@ pub mod key_page;
|
|||
pub mod knob_page;
|
||||
pub mod mqtt;
|
||||
pub mod position;
|
||||
|
||||
pub fn get_default_host_id() -> Box<str> {
|
||||
"local".to_owned().into_boxed_str()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue