1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use super::RillClient;
use super::RillClientLink;
use anyhow::Error;
use async_trait::async_trait;
use derive_more::From;
use meio::{ActionHandler, Context, Interact, Interaction, InteractionResponder, InteractionTask};

pub struct WaitReady;

impl Interaction for WaitReady {
    type Output = ();
}

impl RillClientLink {
    pub async fn wait_ready(&mut self) -> InteractionTask<WaitReady> {
        let msg = WaitReady;
        self.address.interact(msg)
    }
}

#[derive(From)]
pub(super) struct Notifier {
    responder: InteractionResponder<()>,
}

impl Notifier {
    fn notify(self) {
        let res = self.responder.send(Ok(()));
        if res.is_err() {
            log::error!("Can't notify a listener that the client is ready.");
        }
    }
}

#[async_trait]
impl ActionHandler<Interact<WaitReady>> for RillClient {
    async fn handle(
        &mut self,
        input: Interact<WaitReady>,
        _ctx: &mut Context<Self>,
    ) -> Result<(), Error> {
        let notifier = Notifier::from(input.responder);
        if self.sender.is_some() {
            notifier.notify();
        } else {
            self.awaiting_clients.push_back(notifier);
        }
        Ok(())
    }
}

impl RillClient {
    pub(super) fn notify_awaiting_clients(&mut self) {
        for notifier in self.awaiting_clients.drain(..) {
            notifier.notify();
        }
    }
}