Skip to content

Commit 6ec6a78

Browse files
ids1024jackpot51
authored andcommitted
improv: Add DaemonDummy
This adds some boilerplate for each command, but it eliminates the annoying `daemon_opt: Option<Rc<dyn Daemon>>` nonsense. This could also be useful for unit tests.
1 parent 862562c commit 6ec6a78

File tree

6 files changed

+137
-60
lines changed

6 files changed

+137
-60
lines changed

src/application/keyboard.rs

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use super::page::Page;
2424
use super::picker::Picker;
2525

2626
pub struct Keyboard {
27-
pub(crate) daemon_opt: Option<Rc<dyn Daemon>>,
27+
pub(crate) daemon: Rc<dyn Daemon>,
2828
pub(crate) daemon_board: usize,
2929
pub(crate) keymap: HashMap<String, u16>,
3030
pub(crate) keys: RefCell<Vec<Key>>,
@@ -34,7 +34,7 @@ pub struct Keyboard {
3434
}
3535

3636
impl Keyboard {
37-
pub fn new<P: AsRef<Path>>(dir: P, daemon_opt: Option<Rc<dyn Daemon>>, daemon_board: usize) -> Rc<Self> {
37+
pub fn new<P: AsRef<Path>>(dir: P, daemon: Rc<dyn Daemon>, daemon_board: usize) -> Rc<Self> {
3838
let dir = dir.as_ref();
3939

4040
let keymap_csv = fs::read_to_string(dir.join("keymap.csv"))
@@ -43,24 +43,20 @@ impl Keyboard {
4343
.expect("Failed to load layout.csv");
4444
let physical_json = fs::read_to_string(dir.join("physical.json"))
4545
.expect("Failed to load physical.json");
46-
Self::new_data(&keymap_csv, &layout_csv, &physical_json, daemon_opt, daemon_board)
46+
Self::new_data(&keymap_csv, &layout_csv, &physical_json, daemon, daemon_board)
4747
}
4848

49-
fn new_layout(layout: Layout, daemon_opt: Option<Rc<dyn Daemon>>, daemon_board: usize) -> Rc<Self> {
49+
fn new_layout(layout: Layout, daemon: Rc<dyn Daemon>, daemon_board: usize) -> Rc<Self> {
5050
let mut keys = layout.keys();
5151
for key in keys.iter_mut() {
5252
for layer in 0..2 {
5353
println!(" Layer {}", layer);
54-
let scancode = if let Some(ref daemon) = daemon_opt {
55-
match daemon.keymap_get(daemon_board, layer, key.electrical.0, key.electrical.1) {
56-
Ok(value) => value,
57-
Err(err) => {
58-
eprintln!("Failed to read scancode: {:?}", err);
59-
0
60-
}
54+
let scancode = match daemon.keymap_get(daemon_board, layer, key.electrical.0, key.electrical.1) {
55+
Ok(value) => value,
56+
Err(err) => {
57+
eprintln!("Failed to read scancode: {:?}", err);
58+
0
6159
}
62-
} else {
63-
0
6460
};
6561
println!(" Scancode: {:04X}", scancode);
6662

@@ -75,7 +71,7 @@ impl Keyboard {
7571
}
7672

7773
Rc::new(Self {
78-
daemon_opt,
74+
daemon,
7975
daemon_board,
8076
keymap: layout.keymap,
8177
keys: RefCell::new(keys),
@@ -85,15 +81,15 @@ impl Keyboard {
8581
})
8682
}
8783

88-
pub fn new_board(board: &str, daemon_opt: Option<Rc<dyn Daemon>>, daemon_board: usize) -> Option<Rc<Self>> {
84+
pub fn new_board(board: &str, daemon: Rc<dyn Daemon>, daemon_board: usize) -> Option<Rc<Self>> {
8985
Layout::from_board(board).map(|layout|
90-
Self::new_layout(layout, daemon_opt, daemon_board)
86+
Self::new_layout(layout, daemon, daemon_board)
9187
)
9288
}
9389

94-
fn new_data(keymap_csv: &str, layout_csv: &str, physical_json: &str, daemon_opt: Option<Rc<dyn Daemon>>, daemon_board: usize) -> Rc<Self> {
90+
fn new_data(keymap_csv: &str, layout_csv: &str, physical_json: &str, daemon: Rc<dyn Daemon>, daemon_board: usize) -> Rc<Self> {
9591
let layout = Layout::from_data(keymap_csv, layout_csv, physical_json);
96-
Self::new_layout(layout, daemon_opt, daemon_board)
92+
Self::new_layout(layout, daemon, daemon_board)
9793
}
9894

9995
pub fn layer(&self) -> usize {
@@ -141,16 +137,12 @@ impl Keyboard {
141137
..set_halign(gtk::Align::Start);
142138
};
143139

144-
let max_brightness = if let Some(ref daemon) = self.daemon_opt {
145-
match daemon.max_brightness(self.daemon_board) {
146-
Ok(value) => value as f64,
147-
Err(err) => {
148-
eprintln!("{}", err);
149-
100.0
150-
}
140+
let max_brightness = match self.daemon.max_brightness(self.daemon_board) {
141+
Ok(value) => value as f64,
142+
Err(err) => {
143+
eprintln!("{}", err);
144+
100.0
151145
}
152-
} else {
153-
100.0
154146
};
155147

156148
let brightness_scale = cascade! {
@@ -161,10 +153,8 @@ impl Keyboard {
161153
let kb = self.clone();
162154
brightness_scale.connect_value_changed(move |this| {
163155
let value = this.get_value() as i32;
164-
if let Some(ref daemon) = kb.daemon_opt {
165-
if let Err(err) = daemon.set_brightness(kb.daemon_board, value) {
166-
eprintln!("{}", err);
167-
}
156+
if let Err(err) = kb.daemon.set_brightness(kb.daemon_board, value) {
157+
eprintln!("{}", err);
168158
}
169159
println!("{}", value);
170160

@@ -175,12 +165,7 @@ impl Keyboard {
175165
..set_halign(gtk::Align::Start);
176166
};
177167

178-
let color_keyboard = if let Some(ref daemon) = self.daemon_opt {
179-
ColorKeyboard::new_daemon(daemon.clone(), self.daemon_board)
180-
} else {
181-
182-
ColorKeyboard::new_dummy()
183-
};
168+
let color_keyboard = ColorKeyboard::new_daemon(self.daemon.clone(), self.daemon_board);
184169
let color_button = KeyboardColorButton::new(color_keyboard);
185170
color_button.set_valign(gtk::Align::Center);
186171

src/application/mod.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use gio::prelude::*;
33
use gtk::prelude::*;
44
use std::rc::Rc;
55

6-
use crate::daemon::{Daemon, DaemonClient, daemon_server};
6+
use crate::daemon::{Daemon, DaemonClient, DaemonDummy, daemon_server};
77

88
mod key;
99
mod keyboard;
@@ -51,7 +51,7 @@ fn main_app(app: &gtk::Application, daemon: Rc<dyn Daemon>) {
5151

5252
let mut count = 0;
5353
for (i, board) in boards.iter().enumerate() {
54-
if let Some(keyboard) = Keyboard::new_board(board, Some(daemon.clone()), i) {
54+
if let Some(keyboard) = Keyboard::new_board(board, daemon.clone(), i) {
5555
let widget = main_keyboard(app, keyboard);
5656
board_dropdown.append(Some(&board), &board);
5757
stack.add_named(&widget, &board);
@@ -66,18 +66,27 @@ fn main_app(app: &gtk::Application, daemon: Rc<dyn Daemon>) {
6666
}
6767
}
6868

69-
if count == 0 {
69+
if count == 1 {
7070
eprintln!("Failed to locate any keyboards, showing demo");
71-
let board = "system76/launch_alpha_2";
72-
let keyboard = Keyboard::new_board(board, None, 0)
73-
.expect("Failed to load demo layout");
7471

75-
let widget = main_keyboard(app, keyboard);
76-
board_dropdown.append(Some(board), board);
77-
stack.add_named(&widget, board);
78-
79-
widget.show();
80-
board_dropdown.set_active_id(Some(board));
72+
let daemon = Rc::new(DaemonDummy::new());
73+
let boards = daemon.boards().unwrap();
74+
75+
for (i, board) in boards.iter().enumerate() {
76+
if let Some(keyboard) = Keyboard::new_board(board, daemon.clone(), i) {
77+
let widget = main_keyboard(app, keyboard);
78+
board_dropdown.append(Some(&board), &board);
79+
stack.add_named(&widget, &board);
80+
count += 1;
81+
82+
if count == 1 {
83+
widget.show();
84+
board_dropdown.set_active_id(Some(&board));
85+
}
86+
} else {
87+
eprintln!("Failed to locate layout for '{}'", board);
88+
}
89+
}
8190
}
8291

8392
let vbox = cascade! {

src/application/picker/mod.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,16 +192,14 @@ impl Picker {
192192
" set {}, {}, {} to {:04X}",
193193
layer, k.electrical.0, k.electrical.1, k.scancodes[layer].0
194194
);
195-
if let Some(ref daemon) = kb.daemon_opt {
196-
if let Err(err) = daemon.keymap_set(
197-
kb.daemon_board,
198-
layer as u8,
199-
k.electrical.0,
200-
k.electrical.1,
201-
k.scancodes[layer].0,
202-
) {
203-
eprintln!("Failed to set keymap: {:?}", err);
204-
}
195+
if let Err(err) = kb.daemon.keymap_set(
196+
kb.daemon_board,
197+
layer as u8,
198+
k.electrical.0,
199+
k.electrical.1,
200+
k.scancodes[layer].0,
201+
) {
202+
eprintln!("Failed to set keymap: {:?}", err);
205203
}
206204
}
207205
}));

src/color.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl Hs {
2323
}
2424
}
2525

26-
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
26+
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Default)]
2727
pub struct Rgb {
2828
/// Red
2929
pub r: u8,

src/daemon/dummy.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use std::{
2+
cell::{
3+
Cell,
4+
RefCell,
5+
},
6+
collections::HashMap,
7+
};
8+
9+
use crate::color::Rgb;
10+
use super::Daemon;
11+
12+
#[derive(Default)]
13+
struct BoardDummy {
14+
keymap: RefCell<HashMap<(u8, u8, u8), u16>>,
15+
color: Cell<Rgb>,
16+
brightness: Cell<i32>,
17+
}
18+
19+
pub struct DaemonDummy {
20+
board_names: Vec<String>,
21+
boards: Vec<BoardDummy>,
22+
}
23+
24+
impl DaemonDummy {
25+
fn board(&self, board: usize) -> Result<&BoardDummy, String> {
26+
self.boards.get(board).ok_or("No board".to_string())
27+
}
28+
}
29+
30+
impl DaemonDummy {
31+
pub fn new() -> Self {
32+
let board_names = vec!["system76/launch_alpha_2".to_string()];
33+
let boards = board_names.iter().map(|_| BoardDummy::default()).collect();
34+
Self {
35+
board_names,
36+
boards,
37+
}
38+
}
39+
}
40+
41+
impl Daemon for DaemonDummy {
42+
fn boards(&self) -> Result<Vec<String>, String> {
43+
Ok(self.board_names.clone())
44+
}
45+
46+
fn keymap_get(&self, board: usize, layer: u8, output: u8, input: u8) -> Result<u16, String> {
47+
let keymap = self.board(board)?.keymap.borrow();
48+
Ok(keymap.get(&(layer, output, input)).copied().unwrap_or(0))
49+
}
50+
51+
fn keymap_set(&self, board: usize, layer: u8, output: u8, input: u8, value: u16) -> Result<(), String> {
52+
let mut keymap = self.board(board)?.keymap.borrow_mut();
53+
keymap.insert((layer, output, input), value);
54+
Ok(())
55+
}
56+
57+
fn color(&self, board: usize) -> Result<Rgb, String> {
58+
Ok(self.board(board)?.color.get())
59+
}
60+
61+
fn set_color(&self, board: usize, color: Rgb) -> Result<(), String> {
62+
self.board(board)?.color.set(color);
63+
Ok(())
64+
}
65+
66+
fn max_brightness(&self, _board: usize) -> Result<i32, String> {
67+
Ok(100)
68+
}
69+
70+
fn brightness(&self, board: usize) -> Result<i32, String> {
71+
Ok(self.board(board)?.brightness.get())
72+
}
73+
74+
fn set_brightness(&self, board: usize, brightness: i32) -> Result<(), String> {
75+
self.board(board)?.brightness.set(brightness);
76+
Ok(())
77+
}
78+
79+
fn exit(&self) -> Result<(), String> {
80+
Ok(())
81+
}
82+
}

src/daemon/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ mod client;
99
pub use self::server::DaemonServer;
1010
mod server;
1111

12+
pub use self::dummy::DaemonDummy;
13+
mod dummy;
14+
1215
pub trait DaemonClientTrait {
1316
fn send_command(&self, command: DaemonCommand) -> Result<DaemonResponse, String>;
1417
}

0 commit comments

Comments
 (0)