subscribers - done
This commit is contained in:
@@ -194,8 +194,8 @@
|
||||
|
||||
Добавить возможность добавления callback-ов в объект комнаты, которые срабатывают при добавлении новых устройств в комнату (паттерн Observer).
|
||||
|
||||
- [ ] Использовать динамический полиморфизм (трейт-объекты).
|
||||
- [ ] Можно передавать как объект-subscriber, так и [замыкание](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=06e9dc9bcce297d1e80a22d7e9338ee8).
|
||||
- [x] Использовать динамический полиморфизм (трейт-объекты).
|
||||
- [x] Можно передавать как объект-subscriber, так и [замыкание](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=06e9dc9bcce297d1e80a22d7e9338ee8).
|
||||
|
||||
Добавить example-ы, демонстрирующие новый функционал.
|
||||
|
||||
@@ -205,3 +205,9 @@
|
||||
- Приложение-пример успешно выполняется.
|
||||
- Команды cargo clippy и cargo fmt --check не выводят ошибок и предупреждений.
|
||||
- Присутствуют и успешно выполняются модульные тесты.
|
||||
|
||||
### Демонстационные примеры
|
||||
|
||||
- `src/bin/house_builder.rs` - билдер для умного дома
|
||||
- `src/bin/reporter.rs` - компоновщик для построения отчета
|
||||
- `src/bin/subscribers.rs` - добавление коллбеков в объект комнаты
|
||||
|
||||
22
smart-house/src/bin/subscribers.rs
Normal file
22
smart-house/src/bin/subscribers.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use smart_house::{Device, PowerSocket, Room, Subscriber};
|
||||
|
||||
fn main() {
|
||||
let mut room = Room::default();
|
||||
|
||||
room.subscribe(MySubscriber::default());
|
||||
|
||||
room.subscribe(|dev: &Device| {
|
||||
println!("device added: {}", dev.display());
|
||||
});
|
||||
|
||||
room.insert_device("", PowerSocket::stub(12.0, false).into());
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct MySubscriber {}
|
||||
|
||||
impl Subscriber for MySubscriber {
|
||||
fn on_event(&mut self, dev: &Device) {
|
||||
println!("DEVICE ADDED: {}", dev.display());
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ mod room;
|
||||
mod builders;
|
||||
mod print_status;
|
||||
mod reporter;
|
||||
mod subscriber;
|
||||
mod thermometer;
|
||||
|
||||
pub use builders::{HouseBuilder, RoomBuilder};
|
||||
@@ -17,4 +18,5 @@ pub use power_socket::PowerSocket;
|
||||
pub use print_status::PrintStatus;
|
||||
pub use reporter::Reporter;
|
||||
pub use room::Room;
|
||||
pub use subscriber::Subscriber;
|
||||
pub use thermometer::Thermometer;
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
use crate::{Device, PrintStatus};
|
||||
use crate::{Device, PrintStatus, Subscriber};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::io::Write;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Room {
|
||||
devices: HashMap<String, Device>,
|
||||
subscribers: Vec<Box<dyn Subscriber>>,
|
||||
}
|
||||
|
||||
impl Room {
|
||||
pub fn new(devices: HashMap<String, Device>) -> Self {
|
||||
Self { devices }
|
||||
Self {
|
||||
devices,
|
||||
subscribers: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_device(&self, name: &str) -> Option<&Device> {
|
||||
@@ -21,12 +25,19 @@ impl Room {
|
||||
}
|
||||
|
||||
pub fn insert_device(&mut self, name: &str, device: Device) -> Option<Device> {
|
||||
for subscriber in &mut self.subscribers {
|
||||
subscriber.on_event(&device);
|
||||
}
|
||||
self.devices.insert(name.to_string(), device)
|
||||
}
|
||||
|
||||
pub fn remove_device(&mut self, name: &str) -> Option<Device> {
|
||||
self.devices.remove(name)
|
||||
}
|
||||
|
||||
pub fn subscribe(&mut self, subscriber: impl Subscriber + 'static) {
|
||||
self.subscribers.push(Box::new(subscriber));
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintStatus for Room {
|
||||
@@ -39,6 +50,21 @@ impl PrintStatus for Room {
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Room {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Room")
|
||||
.field("devices", &self.devices)
|
||||
.field("subscribers.len()", &self.subscribers.len())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Room {
|
||||
fn default() -> Self {
|
||||
Room::new(HashMap::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! room {
|
||||
($($key:expr => $dev:expr),* $(,)?) => {
|
||||
|
||||
14
smart-house/src/subscriber.rs
Normal file
14
smart-house/src/subscriber.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use crate::Device;
|
||||
|
||||
pub trait Subscriber {
|
||||
fn on_event(&mut self, device: &Device);
|
||||
}
|
||||
|
||||
impl<F> Subscriber for F
|
||||
where
|
||||
F: Fn(&Device),
|
||||
{
|
||||
fn on_event(&mut self, value: &Device) {
|
||||
self(value)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user