use std::collections::HashMap; use actix::{Actor, Context, Handler, Message, Recipient}; use emgauwa_lib::errors::EmgauwaError; use emgauwa_lib::models::Controller; use emgauwa_lib::types::{ControllerUid, ControllerWsAction}; use futures::executor::block_on; use sqlx::{Pool, Sqlite}; #[derive(Message)] #[rtype(result = "Result<(), EmgauwaError>")] pub struct DisconnectController { pub controller_uid: ControllerUid, } #[derive(Message)] #[rtype(result = "Result<(), EmgauwaError>")] pub struct ConnectController { pub address: Recipient, pub controller: Controller, } #[derive(Message)] #[rtype(result = "Result<(), EmgauwaError>")] pub struct Action { pub controller_uid: ControllerUid, pub action: ControllerWsAction, } pub struct AppServer { pub pool: Pool, pub connected_controllers: HashMap)>, } impl AppServer { pub fn new(pool: Pool) -> AppServer { AppServer { pool, connected_controllers: HashMap::new(), } } } impl Actor for AppServer { type Context = Context; } impl Handler for AppServer { type Result = Result<(), EmgauwaError>; fn handle(&mut self, msg: DisconnectController, _ctx: &mut Self::Context) -> Self::Result { let mut pool_conn = block_on(self.pool.acquire())?; if let Some((controller, _)) = self.connected_controllers.remove(&msg.controller_uid) { if let Err(err) = block_on(controller.c.update_active(&mut pool_conn, false)) { log::error!( "Failed to mark controller {} as inactive: {:?}", controller.c.uid, err ); } } Ok(()) } } impl Handler for AppServer { type Result = Result<(), EmgauwaError>; fn handle(&mut self, msg: ConnectController, _ctx: &mut Self::Context) -> Self::Result { self.connected_controllers .insert(msg.controller.c.uid.clone(), (msg.controller, msg.address)); Ok(()) } } impl Handler for AppServer { type Result = Result<(), EmgauwaError>; fn handle(&mut self, msg: Action, _ctx: &mut Self::Context) -> Self::Result { if let Some((_, address)) = self.connected_controllers.get(&msg.controller_uid) { block_on(address.send(msg.action))? } else { Err(EmgauwaError::Connection(msg.controller_uid)) } } }