logic_mesh/blocks/misc/
random.rs

1// Copyright (c) 2022-2023, Radu Racariu.
2
3use std::time::Duration;
4
5use rand::Rng;
6
7use uuid::Uuid;
8
9use crate::base::output::props::OutputProps;
10use crate::{
11    base::{
12        block::{Block, BlockDesc, BlockProps, BlockState},
13        input::{input_reader::InputReader, Input, InputProps},
14        output::Output,
15    },
16    blocks::utils::{input_as_number, input_to_millis_or_default},
17};
18
19use libhaystack::val::{kind::HaystackKind, Value};
20
21use crate::blocks::{InputImpl, OutputImpl};
22
23/// Generates a random number at the specified frequency.
24/// min and max control the range of the generated random number.
25/// The defaults are 0 and 100.
26#[block]
27#[derive(BlockProps, Debug)]
28#[dis = "Random"]
29#[category = "misc"]
30pub struct Random {
31    #[input(kind = "Number")]
32    pub freq: InputImpl,
33    #[input(kind = "Number")]
34    pub min: InputImpl,
35    #[input(kind = "Number")]
36    pub max: InputImpl,
37    #[output(kind = "Number")]
38    pub out: OutputImpl,
39}
40
41impl Block for Random {
42    async fn execute(&mut self) {
43        let millis = input_to_millis_or_default(&self.freq.val);
44
45        self.wait_on_inputs(Duration::from_millis(millis)).await;
46
47        if !self.out.is_connected() {
48            return;
49        }
50
51        let mut rng = rand::thread_rng();
52
53        let min = input_as_number(&self.min)
54            .map(|v| v.value as i64)
55            .unwrap_or(0);
56        let max = input_as_number(&self.max)
57            .map(|v| v.value as i64)
58            .unwrap_or(100);
59
60        if min > max {
61            self.set_state(BlockState::Fault);
62        } else if self.state() == BlockState::Fault {
63            self.set_state(BlockState::Running);
64        }
65
66        let res = rng.gen_range(min..max);
67
68        self.out.set(Value::make_int(res));
69    }
70}