Made some changes to allow for threading/async in the future

This commit is contained in:
Dreaded_X 2022-12-17 05:36:36 +01:00
parent e88e2fe48b
commit 2103a46416
Signed by: Dreaded_X
GPG Key ID: 76BDEC4E165D8AD9
3 changed files with 24 additions and 29 deletions

View File

@ -14,7 +14,7 @@ impl_cast::impl_cast!(Device, Listener);
impl_cast::impl_cast!(Device, Fullfillment); impl_cast::impl_cast!(Device, Fullfillment);
impl_cast::impl_cast!(Device, OnOff); impl_cast::impl_cast!(Device, OnOff);
pub trait Device: AsFullfillment + AsListener + AsOnOff { pub trait Device: Sync + Send + AsFullfillment + AsListener + AsOnOff {
fn get_id(&self) -> String; fn get_id(&self) -> String;
} }
@ -52,10 +52,6 @@ impl Devices {
get_cast!(Fullfillment); get_cast!(Fullfillment);
get_cast!(OnOff); get_cast!(OnOff);
// pub fn get_google_devices(&mut self) -> HashMap<&str, &mut dyn GoogleHomeDevice> {
// self.devices
// }
pub fn get_device(&mut self, name: &str) -> Option<&mut dyn Device> { pub fn get_device(&mut self, name: &str) -> Option<&mut dyn Device> {
if let Some(device) = self.devices.get_mut(name) { if let Some(device) = self.devices.get_mut(name) {
return Some(device.as_mut()); return Some(device.as_mut());

View File

@ -1,4 +1,4 @@
use std::{time::Duration, rc::Rc, cell::RefCell, process::exit}; use std::{time::Duration, sync::{Arc, RwLock}, process::exit, thread};
use dotenv::dotenv; use dotenv::dotenv;
@ -28,21 +28,28 @@ fn main() {
let (client, connection) = Client::new(mqttoptions, 10); let (client, connection) = Client::new(mqttoptions, 10);
// Create device holder // Create device holder
let devices = Rc::new(RefCell::new(Devices::new())); let devices = Arc::new(RwLock::new(Devices::new()));
// Create a new device and add it to the holder // Create a new device and add it to the holder
devices.borrow_mut().add_device(IkeaOutlet::new("Kettle".into(), Zigbee::new("kitchen/kettle", "zigbee2mqtt/kitchen/kettle"), client.clone())); devices.write().unwrap().add_device(IkeaOutlet::new("Kettle".into(), Zigbee::new("kitchen/kettle", "zigbee2mqtt/kitchen/kettle"), client.clone()));
devices.borrow_mut().add_device(TestOutlet::new()); devices.write().unwrap().add_device(TestOutlet::new());
{ {
for (_, d) in devices.borrow_mut().as_on_offs().iter_mut() { for (_, d) in devices.write().unwrap().as_on_offs().iter_mut() {
d.set_on(true).unwrap(); d.set_on(false).unwrap();
} }
} }
let ptr = Arc::downgrade(&devices);
{
let mut notifier = Notifier::new();
notifier.add_listener(ptr);
notifier.start(connection);
}
// Google Home test
let gc = GoogleHome::new("Dreaded_X"); let gc = GoogleHome::new("Dreaded_X");
let json = r#"{ let json = r#"{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf", "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"inputs": [ "inputs": [
@ -74,18 +81,10 @@ fn main() {
] ]
}"#; }"#;
let request = serde_json::from_str(json).unwrap(); let request = serde_json::from_str(json).unwrap();
{ let mut binding = devices.write().unwrap();
let mut binding = devices.borrow_mut();
let mut ghd = binding.as_fullfillments(); let mut ghd = binding.as_fullfillments();
let response = gc.handle_request(request, &mut ghd).unwrap(); let response = gc.handle_request(request, &mut ghd).unwrap();
println!("{response:?}"); println!("{response:?}");
} }
let mut notifier = Notifier::new();
notifier.add_listener(Rc::downgrade(&devices));
notifier.start(connection);
}

View File

@ -1,13 +1,13 @@
use std::{rc::Weak, cell::RefCell}; use std::sync::{Weak, RwLock};
use rumqttc::{Publish, Connection, Event, Incoming}; use rumqttc::{Publish, Connection, Event, Incoming};
pub trait Listener { pub trait Listener: Sync + Send {
fn notify(&mut self, message: &Publish); fn notify(&mut self, message: &Publish);
} }
pub struct Notifier { pub struct Notifier {
listeners: Vec<Weak<RefCell<dyn Listener>>>, listeners: Vec<Weak<RwLock<dyn Listener>>>,
} }
impl Notifier { impl Notifier {
@ -18,7 +18,7 @@ impl Notifier {
fn notify(&mut self, message: Publish) { fn notify(&mut self, message: Publish) {
self.listeners.retain(|listener| { self.listeners.retain(|listener| {
if let Some(listener) = listener.upgrade() { if let Some(listener) = listener.upgrade() {
listener.borrow_mut().notify(&message); listener.write().unwrap().notify(&message);
return true; return true;
} }
@ -26,7 +26,7 @@ impl Notifier {
}) })
} }
pub fn add_listener<T: Listener + 'static>(&mut self, listener: Weak<RefCell<T>>) { pub fn add_listener<T: Listener + 'static>(&mut self, listener: Weak<RwLock<T>>) {
self.listeners.push(listener); self.listeners.push(listener);
} }