subscribers - done
This commit is contained in:
@@ -194,8 +194,8 @@
|
|||||||
|
|
||||||
Добавить возможность добавления callback-ов в объект комнаты, которые срабатывают при добавлении новых устройств в комнату (паттерн Observer).
|
Добавить возможность добавления callback-ов в объект комнаты, которые срабатывают при добавлении новых устройств в комнату (паттерн Observer).
|
||||||
|
|
||||||
- [ ] Использовать динамический полиморфизм (трейт-объекты).
|
- [x] Использовать динамический полиморфизм (трейт-объекты).
|
||||||
- [ ] Можно передавать как объект-subscriber, так и [замыкание](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=06e9dc9bcce297d1e80a22d7e9338ee8).
|
- [x] Можно передавать как объект-subscriber, так и [замыкание](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=06e9dc9bcce297d1e80a22d7e9338ee8).
|
||||||
|
|
||||||
Добавить example-ы, демонстрирующие новый функционал.
|
Добавить example-ы, демонстрирующие новый функционал.
|
||||||
|
|
||||||
@@ -205,3 +205,9 @@
|
|||||||
- Приложение-пример успешно выполняется.
|
- Приложение-пример успешно выполняется.
|
||||||
- Команды cargo clippy и cargo fmt --check не выводят ошибок и предупреждений.
|
- Команды 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 builders;
|
||||||
mod print_status;
|
mod print_status;
|
||||||
mod reporter;
|
mod reporter;
|
||||||
|
mod subscriber;
|
||||||
mod thermometer;
|
mod thermometer;
|
||||||
|
|
||||||
pub use builders::{HouseBuilder, RoomBuilder};
|
pub use builders::{HouseBuilder, RoomBuilder};
|
||||||
@@ -17,4 +18,5 @@ pub use power_socket::PowerSocket;
|
|||||||
pub use print_status::PrintStatus;
|
pub use print_status::PrintStatus;
|
||||||
pub use reporter::Reporter;
|
pub use reporter::Reporter;
|
||||||
pub use room::Room;
|
pub use room::Room;
|
||||||
|
pub use subscriber::Subscriber;
|
||||||
pub use thermometer::Thermometer;
|
pub use thermometer::Thermometer;
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
use crate::{Device, PrintStatus};
|
use crate::{Device, PrintStatus, Subscriber};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Room {
|
pub struct Room {
|
||||||
devices: HashMap<String, Device>,
|
devices: HashMap<String, Device>,
|
||||||
|
subscribers: Vec<Box<dyn Subscriber>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Room {
|
impl Room {
|
||||||
pub fn new(devices: HashMap<String, Device>) -> Self {
|
pub fn new(devices: HashMap<String, Device>) -> Self {
|
||||||
Self { devices }
|
Self {
|
||||||
|
devices,
|
||||||
|
subscribers: Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device(&self, name: &str) -> Option<&Device> {
|
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> {
|
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)
|
self.devices.insert(name.to_string(), device)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_device(&mut self, name: &str) -> Option<Device> {
|
pub fn remove_device(&mut self, name: &str) -> Option<Device> {
|
||||||
self.devices.remove(name)
|
self.devices.remove(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn subscribe(&mut self, subscriber: impl Subscriber + 'static) {
|
||||||
|
self.subscribers.push(Box::new(subscriber));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrintStatus for Room {
|
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_export]
|
||||||
macro_rules! room {
|
macro_rules! room {
|
||||||
($($key:expr => $dev:expr),* $(,)?) => {
|
($($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