aboutsummaryrefslogtreecommitdiff
path: root/src/world.rs
blob: 1fbc4fe5bde5ae2f0a087046049c46c93bfba29b (plain)
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
use std::collections::HashMap;
use std::sync::mpsc::{self, Receiver, SyncSender};
use std::thread;

use uuid::Uuid;

use crate::actor::{Actorful, Value, Slot};

const CHANNEL_SIZE: usize = 5;

pub struct ActorThreadId(Uuid);

#[derive(Default)]
pub struct World {
    actor_types: HashMap<String, Box<dyn Actorful + Send>>,
    actors: HashMap<ActorThreadId, String>,
}

impl World {
    pub fn upsert_actor_type(&mut self, name: String, actor: Box<dyn Actorful + Send>) {
        self.actor_types.insert(name, actor);
    }

    pub fn spawn_actor(&mut self, r#type: &str) -> (Uuid, HashMap<String, SyncSender<Value>>, HashMap<String, Receiver<Value>>) {
        fn make_channels(slot: Slot) -> ((String, SyncSender<Value>), (String, Receiver<Value>)) {
            let (sender, receiver) = mpsc::sync_channel::<Value>(CHANNEL_SIZE);
            ((slot.name.clone(), sender), (slot.name, receiver))
        }

        let actor = self.actor_types.get(r#type).unwrap();
        let actor = actor.boxed_clone();
        let input_slots = actor.inputs();
        let (input_senders, input_receivers) = input_slots
            .into_iter()
            .map(make_channels)
            .unzip();
        let output_slots = actor.outputs();
        let (output_senders, output_receivers) = output_slots
            .into_iter()
            .map(make_channels)
            .unzip();
        let id = Uuid::new_v4();
        thread::Builder::new()
            .name(id.to_string())
            .spawn(actor.launch(input_receivers, output_senders, self))
            .unwrap();
        (id, input_senders, output_receivers)
    }
}