Skip to main content

ferrum_flow/
node.rs

1use std::fmt::Display;
2
3use gpui::{Bounds, Pixels, Point, Size, px};
4use serde::{Deserialize, Serialize};
5use serde_json::json;
6
7use crate::Graph;
8
9pub const DEFAULT_NODE_WIDTH: Pixels = px(120.0);
10pub const DEFAULT_NODE_HEIGHT: Pixels = px(60.0);
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13pub struct NodeId(pub u64);
14
15impl Display for NodeId {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        write!(f, "{}", self.0)
18    }
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct Node {
23    pub id: NodeId,
24    pub node_type: String,
25    pub x: Pixels,
26    pub y: Pixels,
27    pub size: Size<Pixels>,
28
29    pub inputs: Vec<PortId>,
30    pub outputs: Vec<PortId>,
31    pub data: serde_json::Value,
32}
33
34impl Node {
35    pub fn new(id: u64, x: f32, y: f32) -> Self {
36        Self {
37            id: NodeId(id),
38            node_type: String::new(),
39            x: x.into(),
40            y: y.into(),
41            size: Size {
42                width: DEFAULT_NODE_WIDTH,
43                height: DEFAULT_NODE_HEIGHT,
44            },
45            inputs: vec![],
46            outputs: vec![],
47            data: json!({}),
48        }
49    }
50
51    pub fn node_type(mut self, ty: impl Into<String>) -> Self {
52        self.node_type = ty.into();
53        self
54    }
55
56    pub fn point(&self) -> Point<Pixels> {
57        Point::new(self.x, self.y)
58    }
59
60    pub fn bounds(&self) -> Bounds<Pixels> {
61        Bounds::new(self.point(), self.size)
62    }
63
64    pub fn set_size(mut self, size: Size<Pixels>) -> Self {
65        self.size = size;
66        self
67    }
68
69    pub fn output(mut self, id: PortId) -> Self {
70        self.outputs.push(id);
71        self
72    }
73
74    pub fn input(mut self, id: PortId) -> Self {
75        self.inputs.push(id);
76        self
77    }
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
81pub struct PortId(pub u64);
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
84pub enum PortKind {
85    Input,
86    Output,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct Port {
91    pub id: PortId,
92    pub kind: PortKind,
93    pub index: usize,
94    pub node_id: NodeId,
95}
96
97impl Port {
98    pub fn new_input(id: u64, node_id: u64, index: usize) -> Self {
99        Self {
100            id: PortId(id),
101            kind: PortKind::Input,
102            index,
103            node_id: NodeId(node_id),
104        }
105    }
106    pub fn new_output(id: u64, node_id: u64, index: usize) -> Self {
107        Self {
108            id: PortId(id),
109            kind: PortKind::Output,
110            index,
111            node_id: NodeId(node_id),
112        }
113    }
114}
115
116pub struct NodeBuilder {
117    node_type: String,
118    x: Pixels,
119    y: Pixels,
120    size: Size<Pixels>,
121    input_count: usize,
122    output_count: usize,
123    data: serde_json::Value,
124}
125
126impl NodeBuilder {
127    pub fn new(node_type: impl Into<String>) -> Self {
128        Self {
129            node_type: node_type.into(),
130            x: px(0.0),
131            y: px(0.0),
132            size: Size {
133                width: DEFAULT_NODE_WIDTH,
134                height: DEFAULT_NODE_HEIGHT,
135            },
136            input_count: 0,
137            output_count: 0,
138            data: serde_json::Value::Null,
139        }
140    }
141
142    pub fn position(mut self, x: f32, y: f32) -> Self {
143        self.x = x.into();
144        self.y = y.into();
145        self
146    }
147
148    pub fn size(mut self, w: f32, h: f32) -> Self {
149        self.size = Size {
150            width: w.into(),
151            height: h.into(),
152        };
153        self
154    }
155
156    pub fn input(mut self) -> Self {
157        self.input_count += 1;
158        self
159    }
160
161    pub fn output(mut self) -> Self {
162        self.output_count += 1;
163        self
164    }
165
166    pub fn data(mut self, data: serde_json::Value) -> Self {
167        self.data = data;
168        self
169    }
170
171    pub fn build(self, graph: &mut Graph) -> NodeId {
172        let node_id = graph.next_node_id();
173
174        let mut inputs = Vec::new();
175        let mut outputs = Vec::new();
176
177        // 创建 input ports
178        for i in 0..self.input_count {
179            let port_id = graph.next_port_id();
180
181            graph.ports.insert(
182                port_id,
183                Port {
184                    id: port_id,
185                    kind: PortKind::Input,
186                    index: i,
187                    node_id,
188                },
189            );
190
191            inputs.push(port_id);
192        }
193
194        // 创建 output ports
195        for i in 0..self.output_count {
196            let port_id = graph.next_port_id();
197
198            graph.ports.insert(
199                port_id,
200                Port {
201                    id: port_id,
202                    kind: PortKind::Output,
203                    index: i,
204                    node_id,
205                },
206            );
207
208            outputs.push(port_id);
209        }
210
211        let node = Node {
212            id: node_id,
213            node_type: self.node_type,
214            x: self.x,
215            y: self.y,
216            size: self.size,
217            inputs,
218            outputs,
219            data: self.data,
220        };
221
222        graph.nodes.insert(node_id, node);
223        let order = graph.node_order_mut();
224        order.push(node_id);
225
226        node_id
227    }
228}