pub mod events;
use actix::prelude::*;
use std::sync::Arc;
use crate::entities::user::User;
use self::events::JoinBroadcast;
pub struct Handle {
pub message: actix::Recipient<super::common_events::Message>,
}
pub struct Channel {
pub members: Vec<Addr<User>>,
}
impl Channel {
pub fn new() -> Self {
Self {
members: Vec::new(),
}
}
fn broadcast_message<M>(&self, msg: M) -> impl Future<Output = ()>
where
M: Message + Send + Sync,
M::Result: Send,
Arc<M>: 'static,
User: Handler<Arc<M>>,
{
let mut futures = Vec::with_capacity(self.members.len());
let msg = Arc::new(msg);
for member in &self.members {
futures.push(member.send(msg.clone()));
}
async {
futures_util::future::try_join_all(futures).await.unwrap();
}
}
}
impl Actor for Channel {
type Context = Context<Self>;
}
impl actix::Handler<events::Join> for Channel {
type Result = events::JoinResult;
fn handle(&mut self, msg: events::Join, ctx: &mut Self::Context) -> Self::Result {
self.members.push(msg.user.clone());
ctx.spawn(
self.broadcast_message(JoinBroadcast::from(msg))
.into_actor(self),
);
Ok(Handle {
message: ctx.address().recipient(),
})
}
}
impl actix::Handler<super::common_events::Message> for Channel {
type Result = ();
fn handle(
&mut self,
msg: super::common_events::Message,
ctx: &mut Self::Context,
) -> Self::Result {
ctx.spawn(self.broadcast_message(msg).into_actor(self));
}
}