Skip to content

Commit 1e74d77

Browse files
Merge pull request #97 from festim-dev/simplify-functions
Simplify function nodes
2 parents c0239b7 + 7ea0357 commit 1e74d77

File tree

6 files changed

+24
-89
lines changed

6 files changed

+24
-89
lines changed

src/CustomHandle.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import { Handle, useNodeConnections } from '@xyflow/react';
44
const CustomHandle = (props) => {
55
const connections = useNodeConnections({
66
handleType: props.type,
7+
handleId: props.id,
78
});
89

910
return (
1011
<Handle
1112
{...props}
12-
isConnectable={connections.length < props.connectionCount}
13+
isConnectable={connections.length < 1}
1314
/>
1415
);
1516
};

src/FunctionNode.jsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,14 @@ export function createFunctionNode(numInputs, numOutputs) {
2222
for (let i = 0; i < numInputs; i++) {
2323
const handleId = `target-${i}`;
2424
const topPercentage = numInputs === 1 ? 50 : ((i + 1) / (numInputs + 1)) * 100;
25-
const connectionCount = data?.maxConnections?.[handleId] || 1;
26-
25+
2726
inputHandles.push(
2827
<CustomHandle
2928
key={handleId}
3029
id={handleId}
3130
type="target"
3231
position="left"
3332
style={{ ...handleStyle, top: `${topPercentage}%` }}
34-
connectionCount={connectionCount}
3533
/>
3634
);
3735

src/convert_to_python.py

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22
import os
33
from inspect import signature
44

5-
from pathsim.blocks import Scope
5+
from pathsim.blocks import Scope, Function
66
from .custom_pathsim_blocks import (
77
Process,
88
Splitter,
99
Bubbler,
1010
FestimWall,
11-
Function1to1,
12-
Function2to2,
1311
)
1412
from .pathsim_utils import (
1513
map_str_to_object,
@@ -174,19 +172,10 @@ def make_edge_data(data: dict) -> list[dict]:
174172
raise ValueError(
175173
f"Invalid source handle '{edge['sourceHandle']}' for {edge}."
176174
)
177-
elif isinstance(block, Function1to1):
178-
# Function1to1 has only one output port
179-
output_index = 0
180-
elif isinstance(block, Function2to2):
181-
# Function2to2 has two output ports
182-
if edge["sourceHandle"] == "output-0":
183-
output_index = 0
184-
elif edge["sourceHandle"] == "output-1":
185-
output_index = 1
186-
else:
187-
raise ValueError(
188-
f"Invalid source handle '{edge['sourceHandle']}' for {edge}."
189-
)
175+
elif isinstance(block, Function):
176+
# Function outputs are always in order, so we can use the handle directly
177+
assert edge["sourceHandle"], edge
178+
output_index = int(edge["sourceHandle"].replace("source-", ""))
190179
else:
191180
# make sure that the source block has only one output port (ie. that sourceHandle is None)
192181
assert edge["sourceHandle"] is None, (
@@ -215,19 +204,9 @@ def make_edge_data(data: dict) -> list[dict]:
215204
raise ValueError(
216205
f"Invalid target handle '{edge['targetHandle']}' for {edge}."
217206
)
218-
elif isinstance(target_block, Function1to1):
219-
# Function1to1 has only one input port
220-
input_index = 0
221-
elif isinstance(target_block, Function2to2):
222-
# Function2to2 has two input ports
223-
if edge["targetHandle"] == "input-0":
224-
input_index = 0
225-
elif edge["targetHandle"] == "input-1":
226-
input_index = 1
227-
else:
228-
raise ValueError(
229-
f"Invalid target handle '{edge['targetHandle']}' for {edge}."
230-
)
207+
elif isinstance(target_block, Function):
208+
# Function inputs are always in order, so we can use the handle directly
209+
input_index = int(edge["targetHandle"].replace("target-", ""))
231210
else:
232211
# make sure that the target block has only one input port (ie. that targetHandle is None)
233212
assert edge["targetHandle"] is None, (

src/custom_pathsim_blocks.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -94,28 +94,6 @@ def create_reset_events(self):
9494
]
9595

9696

97-
class Function1to1(pathsim.blocks.Function):
98-
"""Function block with 1 input and 1 output."""
99-
100-
def __init__(self, expression="lambda x: 1*x"):
101-
if isinstance(expression, str):
102-
func = eval(expression)
103-
else:
104-
func = expression
105-
super().__init__(func=func)
106-
107-
108-
class Function2to2(pathsim.blocks.Function):
109-
"""Function block with 2 inputs and 2 outputs."""
110-
111-
def __init__(self, expression="lambda x, y:1*x, 1*y"):
112-
if isinstance(expression, str):
113-
func = eval(expression)
114-
else:
115-
func = expression
116-
super().__init__(func=func)
117-
118-
11997
# BUBBLER SYSTEM
12098

12199

src/pathsim_utils.py

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
Amplifier,
1414
Adder,
1515
Multiplier,
16-
# Function,
16+
Function,
1717
Delay,
1818
RNG,
1919
PID,
@@ -28,8 +28,6 @@
2828
Bubbler,
2929
FestimWall,
3030
Integrator,
31-
Function1to1,
32-
Function2to2,
3331
)
3432
from flask import jsonify
3533
import inspect
@@ -57,8 +55,8 @@
5755
"rng": RNG,
5856
"pid": PID,
5957
"integrator": Integrator,
60-
"function": Function1to1,
61-
"function2to2": Function2to2,
58+
"function": Function,
59+
"function2to2": Function,
6260
"delay": Delay,
6361
"bubbler": Bubbler,
6462
"wall": FestimWall,
@@ -383,19 +381,10 @@ def make_connections(nodes, edges, blocks) -> list[Connection]:
383381
raise ValueError(
384382
f"Invalid source handle '{edge['sourceHandle']}' for {edge}."
385383
)
386-
elif isinstance(block, Function1to1):
387-
# Function1to1 has only one output port
388-
output_index = 0
389-
elif isinstance(block, Function2to2):
390-
# Function2to2 has two output ports
391-
if edge["sourceHandle"] == "output-0":
392-
output_index = 0
393-
elif edge["sourceHandle"] == "output-1":
394-
output_index = 1
395-
else:
396-
raise ValueError(
397-
f"Invalid source handle '{edge['sourceHandle']}' for {edge}."
398-
)
384+
elif isinstance(block, Function):
385+
# Function outputs are always in order, so we can use the handle directly
386+
assert edge["sourceHandle"], edge
387+
output_index = int(edge["sourceHandle"].replace("source-", ""))
399388
else:
400389
# make sure that the source block has only one output port (ie. that sourceHandle is None)
401390
assert edge["sourceHandle"] is None, (
@@ -424,19 +413,9 @@ def make_connections(nodes, edges, blocks) -> list[Connection]:
424413
raise ValueError(
425414
f"Invalid target handle '{edge['targetHandle']}' for {edge}."
426415
)
427-
elif isinstance(target_block, Function1to1):
428-
# Function1to1 has only one input port
429-
input_index = 0
430-
elif isinstance(target_block, Function2to2):
431-
# Function2to2 has two input ports
432-
if edge["targetHandle"] == "input-0":
433-
input_index = 0
434-
elif edge["targetHandle"] == "input-1":
435-
input_index = 1
436-
else:
437-
raise ValueError(
438-
f"Invalid target handle '{edge['targetHandle']}' for {edge}."
439-
)
416+
elif isinstance(target_block, Function):
417+
# Function inputs are always in order, so we can use the handle directly
418+
input_index = int(edge["targetHandle"].replace("target-", ""))
440419
else:
441420
# make sure that the target block has only one input port (ie. that targetHandle is None)
442421
assert edge["targetHandle"] is None, (

test/test_convert_python.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"type": "function",
3030
"data": {
3131
"label": "func_block",
32-
"expression": "lambda x: x * 2 + 1",
32+
"func": "lambda x: x * 2 + 1",
3333
},
3434
},
3535
{
@@ -63,7 +63,7 @@
6363
"target": "4",
6464
"id": "e3-4",
6565
"sourceHandle": None,
66-
"targetHandle": None,
66+
"targetHandle": "target-0",
6767
},
6868
{
6969
"source": "3",
@@ -76,7 +76,7 @@
7676
"source": "4",
7777
"target": "5",
7878
"id": "e4-5",
79-
"sourceHandle": None,
79+
"sourceHandle": "source-0",
8080
"targetHandle": None,
8181
},
8282
],

0 commit comments

Comments
 (0)