dfir_lang/graph/ops/
spin.rs

1use quote::quote_spanned;
2
3use super::{
4    OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs,
5    RANGE_0, RANGE_1,
6};
7
8/// This operator emits Unit, and triggers the start of a new tick at the end of each tick,
9/// which will cause spinning-like behavior. Note that `run_available` will run forever,
10/// so in the example below we illustrate running manually for 100 ticks.
11///
12/// ```rustbook
13/// let mut flow = dfir_rs::dfir_syntax! {
14///     spin() -> for_each(|x| println!("tick {}: {:?}", context.current_tick(), x));
15/// };
16/// for _ in 1..100 {
17///     flow.run_tick();
18/// }
19/// ```
20pub const SPIN: OperatorConstraints = OperatorConstraints {
21    name: "spin",
22    categories: &[OperatorCategory::Source],
23    hard_range_inn: RANGE_0,
24    soft_range_inn: RANGE_0,
25    hard_range_out: RANGE_1,
26    soft_range_out: RANGE_1,
27    num_args: 0,
28    persistence_args: RANGE_0,
29    type_args: RANGE_0,
30    is_external_input: false,
31    has_singleton_output: false,
32    flo_type: None,
33    ports_inn: None,
34    ports_out: None,
35    input_delaytype_fn: |_| None,
36    write_fn: |&WriteContextArgs {
37                   context,
38                   op_span,
39                   ident,
40                   is_pull,
41                   ..
42               },
43               _| {
44        assert!(is_pull);
45        let write_iterator = quote_spanned! {op_span=>
46            let #ident = ::std::iter::once(());
47        };
48        let write_iterator_after = quote_spanned! {op_span=>
49            #context.schedule_subgraph(#context.current_subgraph(), true);
50        };
51        Ok(OperatorWriteOutput {
52            write_iterator,
53            write_iterator_after,
54            ..Default::default()
55        })
56    },
57};