protoflow_core/
block.rs

1// This is free and unencumbered software released into the public domain.
2
3use crate::{prelude::fmt, BlockDescriptor, BlockResult, BlockRuntime};
4
5/// A machine-readable identifier for a block in a system.
6///
7/// Only valid within the scope of that system.
8pub type BlockID = usize;
9
10/// A block is an autonomous unit of computation in a system.
11pub trait Block: AsBlock + BlockDescriptor + BlockHooks + Send + Sync {
12    /// Prepares this block for execution.
13    ///
14    /// This is called once before the first call to `execute`.
15    /// This is where to open ports and allocate resources.
16    fn prepare(&mut self, _runtime: &dyn BlockRuntime) -> BlockResult {
17        Ok(())
18    }
19
20    /// Executes this block's computation.
21    fn execute(&mut self, runtime: &dyn BlockRuntime) -> BlockResult;
22}
23
24/// Hooks for `#[derive(Block)]` to tap into block execution.
25#[doc(hidden)]
26pub trait BlockHooks {
27    fn pre_execute(&mut self, _runtime: &dyn BlockRuntime) -> BlockResult {
28        Ok(()) // implemented by protoflow_derive
29    }
30
31    fn post_execute(&mut self, _runtime: &dyn BlockRuntime) -> BlockResult {
32        Ok(()) // implemented by protoflow_derive
33    }
34}
35
36pub trait AsBlock {
37    fn as_block(&self) -> &dyn Block;
38}
39
40impl<T: Block + Sized> AsBlock for T {
41    fn as_block(&self) -> &dyn Block {
42        self
43    }
44}
45
46impl fmt::Debug for dyn Block {
47    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48        f.debug_struct("Block")
49            //.field("name", &self.name())
50            //.field("label", &self.label())
51            .field("inputs", &self.inputs())
52            .field("outputs", &self.outputs())
53            .field("parameters", &self.parameters())
54            .finish()
55    }
56}