Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardware generic #85

Merged
merged 6 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 147 additions & 85 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 9 additions & 5 deletions data/src/config/control.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::rc::Rc;

use hardware::{HItem, Hardware, HardwareBridge, HardwareBridgeT, Mode, Value};
use hardware::{HItem, Hardware, HardwareBridge, Mode, Value};
use serde::{Deserialize, Serialize};

use crate::{
Expand Down Expand Up @@ -43,10 +43,10 @@ impl Control {
}
}

pub fn set_value(
pub fn set_value<H: HardwareBridge>(
&mut self,
value: Value,
bridge: &mut HardwareBridge,
bridge: &mut H,
) -> Result<Value, UpdateError> {
if self.mode_set != Some(Mode::Manual) {
self.set_mode(Mode::Manual, bridge)?;
Expand All @@ -61,7 +61,11 @@ impl Control {
}
}

pub fn set_mode(&mut self, mode: Mode, bridge: &mut HardwareBridge) -> Result<(), UpdateError> {
pub fn set_mode<H: HardwareBridge>(
&mut self,
mode: Mode,
bridge: &mut H,
) -> Result<(), UpdateError> {
if let Some(mode_set) = &self.mode_set {
if mode_set == &mode {
info!("Mode {} is already set for {}.", mode, self.name);
Expand All @@ -79,7 +83,7 @@ impl Control {
Ok(())
}

pub fn get_value(&self, bridge: &mut HardwareBridge) -> Result<Value, UpdateError> {
pub fn get_value<H: HardwareBridge>(&self, bridge: &mut H) -> Result<Value, UpdateError> {
match &self.control_h {
Some(control_h) => bridge
.get_value(&control_h.internal_index)
Expand Down
4 changes: 2 additions & 2 deletions data/src/config/fan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
node::{IsValid, Node, NodeType, ToNode},
update::UpdateError,
};
use hardware::{HItem, Hardware, HardwareBridge, HardwareBridgeT, Value};
use hardware::{HItem, Hardware, HardwareBridge, Value};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
Expand All @@ -20,7 +20,7 @@ pub struct Fan {
}

impl Fan {
pub fn get_value(&self, bridge: &mut HardwareBridge) -> Result<Value, UpdateError> {
pub fn get_value<H: HardwareBridge>(&self, bridge: &mut H) -> Result<Value, UpdateError> {
match &self.fan_h {
Some(fan_h) => bridge
.get_value(&fan_h.internal_index)
Expand Down
4 changes: 2 additions & 2 deletions data/src/config/temp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::rc::Rc;

use hardware::{HItem, Hardware, HardwareBridge, HardwareBridgeT, Value};
use hardware::{HItem, Hardware, HardwareBridge, Value};
use serde::{Deserialize, Serialize};

use crate::{
Expand All @@ -21,7 +21,7 @@ pub struct Temp {
}

impl Temp {
pub fn get_value(&self, bridge: &mut HardwareBridge) -> Result<Value, UpdateError> {
pub fn get_value<H: HardwareBridge>(&self, bridge: &mut H) -> Result<Value, UpdateError> {
match &self.temp_h {
Some(temp_h) => bridge
.get_value(&temp_h.internal_index)
Expand Down
4 changes: 2 additions & 2 deletions data/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ use update::Update;

use crate::dir_manager::DirManager;

pub struct AppState {
pub struct AppState<H: HardwareBridge> {
pub dir_manager: DirManager,
pub bridge: HardwareBridge,
pub bridge: H,
pub app_graph: AppGraph,
pub update: Update,
}
28 changes: 14 additions & 14 deletions data/src/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ impl Update {
/// Update graph in an optimal way. This shouln't be use
/// with a graphical interface.
/// Warning: doesn't call update from the bridge, it's the role of the caller.
pub fn optimized(
pub fn optimized<H: HardwareBridge>(
&mut self,
nodes: &mut Nodes,
root_nodes: &RootNodes,
bridge: &mut HardwareBridge,
bridge: &mut H,
) -> Result<()> {
let mut updated: HashSet<Id> = HashSet::new();
for node_id in root_nodes {
Expand All @@ -62,7 +62,7 @@ impl Update {

/// Doesn't update root nodes and doesn't re update nodes that could have been updated (fans).
/// Warning: doesn't call update from the bridge, it's the role of the caller.
pub fn all(&mut self, nodes: &mut Nodes, bridge: &mut HardwareBridge) -> Result<()> {
pub fn all<H: HardwareBridge>(&mut self, nodes: &mut Nodes, bridge: &mut H) -> Result<()> {
let ids_to_update_sorted: Vec<Id>;
{
let mut key_values = nodes.iter().collect::<Vec<_>>();
Expand All @@ -84,10 +84,10 @@ impl Update {
Ok(())
}

pub fn nodes_which_update_can_change(
pub fn nodes_which_update_can_change<H: HardwareBridge>(
&mut self,
nodes: &mut Nodes,
bridge: &mut HardwareBridge,
bridge: &mut H,
) -> Result<()> {
for node in nodes.values_mut() {
let value = match &mut node.node_type {
Expand Down Expand Up @@ -120,11 +120,11 @@ impl Update {
Ok(())
}

fn set_node_to_auto(
fn set_node_to_auto<H: HardwareBridge>(
&mut self,
nodes: &mut Nodes,
node_id: &Id,
bridge: &mut HardwareBridge,
bridge: &mut H,
) -> Result<()> {
let Some(node) = nodes.get_mut(node_id) else {
return Err(UpdateError::NodeNotFound(*node_id));
Expand All @@ -136,11 +136,11 @@ impl Update {
}
}

pub fn set_valid_root_nodes_to_auto(
pub fn set_valid_root_nodes_to_auto<H: HardwareBridge>(
&mut self,
nodes: &mut Nodes,
root_nodes: &RootNodes,
bridge: &mut HardwareBridge,
bridge: &mut H,
) {
for node_id in root_nodes {
if Self::validate_rec(nodes, node_id) {
Expand All @@ -154,11 +154,11 @@ impl Update {
}
}

pub fn set_invalid_root_nodes_to_auto(
pub fn set_invalid_root_nodes_to_auto<H: HardwareBridge>(
&mut self,
nodes: &mut Nodes,
root_nodes: &RootNodes,
bridge: &mut HardwareBridge,
bridge: &mut H,
) {
for node_id in root_nodes {
if !Self::validate_rec(nodes, node_id) {
Expand Down Expand Up @@ -189,11 +189,11 @@ impl Update {
true
}

fn update_rec(
fn update_rec<H: HardwareBridge>(
nodes: &mut Nodes,
node_id: &Id,
updated: &mut HashSet<Id>,
bridge: &mut HardwareBridge,
bridge: &mut H,
) -> Result<Option<Value>> {
if updated.contains(node_id) {
return match nodes.get(node_id) {
Expand Down Expand Up @@ -247,7 +247,7 @@ impl Update {
}

impl Node {
fn update(&mut self, input_values: &[Value], bridge: &mut HardwareBridge) -> Result<()> {
fn update<H: HardwareBridge>(&mut self, input_values: &[Value], bridge: &mut H) -> Result<()> {
let value = match &mut self.node_type {
crate::node::NodeType::Control(control) => {
let input_value = input_values[0];
Expand Down
1 change: 0 additions & 1 deletion hardware/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ thiserror.workspace = true
log.workspace = true
serde.workspace = true
ouroboros = "0.18"
enum_dispatch = "0.3"
rand = { version = "0.8", optional = true }
derive_more.workspace = true

Expand Down
9 changes: 3 additions & 6 deletions hardware/src/fake_hardware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt::Debug;

use rand::Rng;

use crate::{HItem, Hardware, HardwareBridgeT, Mode, Value};
use crate::{HItem, Hardware, HardwareBridge, Mode, Value};

pub struct FakeHardwareBridge {
hardware: Hardware,
Expand All @@ -18,8 +18,8 @@ static TEMP_INTERNAL_INDEX: usize = 0;
static FAN_INTERNAL_INDEX: usize = 1;
static CONTROL_INTERNAL_INDEX: usize = 2;

impl FakeHardwareBridge {
pub fn new() -> crate::Result<Self> {
impl HardwareBridge for FakeHardwareBridge {
fn new() -> crate::Result<Self> {
let mut hardware = Hardware::default();

let temp1 = HItem {
Expand Down Expand Up @@ -64,9 +64,6 @@ impl FakeHardwareBridge {

Ok(Self { hardware })
}
}

impl HardwareBridgeT for FakeHardwareBridge {
fn hardware(&self) -> &Hardware {
&self.hardware
}
Expand Down
63 changes: 17 additions & 46 deletions hardware/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use derive_more::Display;
use enum_dispatch::enum_dispatch;
use serde::Serialize;
use std::{fmt::Debug, rc::Rc, time::Duration};
use thiserror::Error;
Expand All @@ -8,19 +7,13 @@ use thiserror::Error;
extern crate log;

#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "linux")]
use linux::LinuxBridge;
pub mod linux;

#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
use windows::WindowsBridge;
pub mod windows;

#[cfg(feature = "fake_hardware")]
mod fake_hardware;
#[cfg(feature = "fake_hardware")]
use fake_hardware::FakeHardwareBridge;
pub mod fake_hardware;

#[derive(Error, Debug)]
pub enum HardwareError {
Expand Down Expand Up @@ -80,39 +73,26 @@ pub enum Mode {
Specific(Value),
}

/// Use this type to interact with the hardware.
/// Only one implementation will be used at runtime. Using enum
/// instead of a trait have better performance.
#[enum_dispatch]
pub enum HardwareBridge {
#[cfg(target_os = "windows")]
WindowsBridge,
/// Try to construct a new hardware bridge
pub fn new() -> Result<impl HardwareBridge> {
#[cfg(feature = "fake_hardware")]
return fake_hardware::FakeHardwareBridge::new();

#[cfg(target_os = "linux")]
LinuxBridge,
#[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))]
return windows::WindowsBridge::new();

#[cfg(feature = "fake_hardware")]
FakeHardwareBridge,
#[cfg(all(not(feature = "fake_hardware"), target_os = "linux"))]
return linux::LinuxBridge::new();
}

impl HardwareBridge {
/// Try to construct a new hardware bridge
#[allow(unreachable_code)]
pub fn new() -> Result<Self> {
#[cfg(feature = "fake_hardware")]
return Ok(Self::FakeHardwareBridge(FakeHardwareBridge::new()?));
pub trait HardwareBridge {
/// Approximative time to update sensors on my pc
const TIME_TO_UPDATE: Duration = Duration::from_millis(0);

#[cfg(target_os = "windows")]
return Ok(Self::WindowsBridge(WindowsBridge::new()?));
fn new() -> Result<Self>
where
Self: Sized;

#[cfg(target_os = "linux")]
return Ok(Self::LinuxBridge(LinuxBridge::new()?));
}
}

/// All variant of HardwareBridge will implement this trait
#[enum_dispatch(HardwareBridge)]
pub trait HardwareBridgeT {
fn hardware(&self) -> &Hardware;

fn get_value(&mut self, internal_index: &usize) -> Result<Value>;
Expand All @@ -131,12 +111,3 @@ pub trait HardwareBridgeT {
Ok(())
}
}

// todo: move this 2 line in HardwareBridgeT when enum_dispatch support const value

/// Approximative time to update sensors on my pc
#[cfg(all(not(feature = "fake_hardware"), target_os = "windows"))]
pub const TIME_TO_UPDATE: Duration = Duration::from_millis(250);

#[cfg(any(feature = "fake_hardware", target_os = "linux"))]
pub const TIME_TO_UPDATE: Duration = Duration::from_millis(0);
11 changes: 4 additions & 7 deletions hardware/src/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{fmt::Debug, rc::Rc};
use lm_sensors::{feature, value, ChipRef, FeatureRef, LMSensors, SubFeatureRef};
use thiserror::Error;

use crate::{HItem, Hardware, HardwareBridgeT, HardwareError, Mode, Value};
use crate::{HItem, Hardware, HardwareBridge, HardwareError, Mode, Value};
use ouroboros::self_referencing;

// https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
Expand All @@ -13,7 +13,7 @@ static DEFAULT_PWM_ENABLE: f64 = 5.0;
static MANUAL_MODE: f64 = 1.0;

#[self_referencing]
pub struct LinuxBridgeSelfRef {
struct LinuxBridgeSelfRef {
lib: LMSensors,
#[borrows(lib)]
#[not_covariant]
Expand Down Expand Up @@ -214,8 +214,8 @@ fn generate_hardware<'a>(
sensors
}

impl LinuxBridge {
pub fn new() -> crate::Result<Self> {
impl HardwareBridge for LinuxBridge {
fn new() -> crate::Result<Self> {
let mut hardware = Hardware::default();

let lib = match lm_sensors::Initializer::default().initialize() {
Expand All @@ -238,9 +238,6 @@ impl LinuxBridge {
hardware,
})
}
}

impl HardwareBridgeT for LinuxBridge {
fn hardware(&self) -> &Hardware {
&self.hardware
}
Expand Down
Loading