22
33
44class Linkable ():
5+ """ This class represents a Linkable object
6+ an object that can be connected to 'linked_nodes_max_count' other elements
7+ """
58 name = None
69 linked_nodes = None
710 linked_nodes_max_count = 0
811
912 def __init__ (self , name , linked_nodes_max_count = 1 , * args , ** kwargs ):
13+ """Args:
14+ name (str): the object string identifier.
15+ linked_nodes_max_count: the maximum number of nodes that can link to.
16+ """
17+
1018 self .name = name
1119 self .linked_nodes_max_count = linked_nodes_max_count
1220 self .linked_nodes = []
1321
1422 def link (self , node ):
23+ """Creates a new link.
24+
25+ Args:
26+ node (Linkable): The node to link to.
27+ """
1528 if not self .is_linked_to (node ):
1629 if self .linked_nodes_max_count > len (self .linked_nodes ):
1730 self .linked_nodes .append (node )
@@ -20,54 +33,116 @@ def link(self, node):
2033 return False
2134
2235 def is_linked (self ):
36+ """Check whether this object is linked to something.
37+
38+ Returns:
39+ result (bool): If the node is linked to something.
40+ """
2341 return len (self .linked_nodes ) > 0
2442
2543 def is_linked_to (self , node ):
44+ """Check whether this object is linked to the given node.
45+
46+ Args:
47+ node (Linkable): The node to be checked if linked to.
48+
49+ Returns:
50+ result (bool): If this node is linked to the given node.
51+ """
2652 return node in self .linked_nodes
2753
2854 def unlink (self , node = None ):
55+ """Removes a link to a specific node.
56+ If the given node is null, removes all the links.
57+
58+ Args:
59+ node (Linkable): The node to be unlinked. None to remove all links.
60+ """
2961 if node is None :
3062 self .linked_nodes = []
3163 return
3264 self .linked_nodes .remove (node )
3365
3466
3567class Input (Linkable ):
68+ """An input element of a FunctionBlock.
69+ """
3670 default = None
3771 typ = None
3872
3973 def __init__ (self , name , default = inspect .Parameter .empty , typ = None ):
74+ """Args:
75+ name (str): The name of the input.
76+ default (any): The default value of the input.
77+ type (type): The input type.
78+ """
4079 Linkable .__init__ (self , name , linked_nodes_max_count = 1 )
4180 self .default = default
4281 self .typ = typ
4382
4483 def get_value (self ):
84+ """Returns the input value.
85+ The value is the default one if the Input is not linked,
86+ or the value given from the link.
87+
88+ Returns:
89+ result (any): The input value.
90+ """
4591 if not self .is_linked ():
4692 return self .default
4793 return self .linked_nodes [0 ].get_value ()
4894
4995 def has_default (self ):
96+ """Returns whether there is a default value.
97+
98+ Returns:
99+ result (bool): True if this input has a default value.
100+ """
50101 return not (self .default == inspect .Parameter .empty )
51102
52103
53104class Output (Linkable ):
105+ """An output value of a FunctionBlock
106+ """
54107 name = None
55108 typ = None
56109 value = None
57110
58111 def __init__ (self , name , typ = None ):
112+ """Args:
113+ name (str): The name of the output.
114+ type (type): The output type.
115+ """
59116 Linkable .__init__ (self , name , linked_nodes_max_count = 0xff )
60117 self .name = name
61118 self .typ = typ
62119
63120 def get_value (self ):
121+ """Returns the output value.
122+ The value given from the FunctionBlock processing.
123+
124+ Returns:
125+ result (any): The output value.
126+ """
64127 return self .value
65128
66129 def set_value (self , value ):
130+ """Sets the output value.
131+
132+ Args:
133+ value (any): the value to be assigned.
134+ """
67135 self .value = value
68136
69137
70138class FunctionBlock ():
139+ """A FunctionBlock represents a processing unit with its own logic.
140+ The function block must implement the 'do' method that executes the algorithm.
141+ A function block has N inputs, that are the parameters of the 'do' method,
142+ and M outputs that are the result values of the 'do' method.
143+ A function block can have an enabling input to enable or disable the logic exection.
144+ A function block gets executed among the others, in the order given by the execution_priority member.
145+ """
71146 name = None
72147 inputs = None
73148 outputs = None
@@ -88,57 +163,111 @@ def add_annotation(method):
88163 return add_annotation
89164
90165 def __init__ (self , name , execution_priority = 0 ):
166+ """Args:
167+ name (str): The function block name.
168+ execution_priority (int): the order number.
169+ """
91170 self .name = name
92171 self .set_execution_priority (execution_priority )
93172 self .inputs = {}
94173 self .outputs = {}
95174
96175 def set_execution_priority (self , execution_priority ):
176+ """Sets the execution order.
177+
178+ Args:
179+ execution_priority (int): The priority value.
180+ """
97181 self .execution_priority = execution_priority
98182
99183 def add_io (self , io ):
184+ """Adds an Input or Output to the function block.
185+
186+ Args:
187+ io (Input/Output): The io instance.
188+ """
100189 if issubclass (type (io ), Input ):
101190 self .inputs [io .name ] = io
102191 else :
103192 self .outputs [io .name ] = io
104193
105194 def add_enabling_input (self ):
195+ """Adds an enabling input.
196+ """
106197 self .add_io (Input ('EN' , False ))
107198
108199 def remove_enabling_input (self ):
200+ """Removes the enabling input and the eventual link.
201+ """
109202 self .inputs ['EN' ].unlink ()
110203 del self .inputs ['EN' ]
111204
112205 @decorate_process ([])
113206 def do (self ):
207+ """Implements the FunctionBlock logic.
208+ Inputs are passed to this function as parameters by the Process.
209+ Results are assigned to the Outputs by the Process.
210+
211+ Returns:
212+ result (any): The result value.
213+ """
114214 return None
115215
116216
117217class Link ():
218+ """Represents the link between two Linkable nodes.
219+ """
118220 source = None
119221 destination = None
120222 def __init__ (self , source_widget , destination_widget ):
223+ """Args:
224+ source_widget (Linkable): a node participating to the link.
225+ destination_widget (Linkable): a node participating to the link.
226+ """
121227 self .source = source_widget
122228 self .destination = destination_widget
123229
124230 def unlink (self ):
231+ """Deletes the link.
232+ """
125233 self .source .unlink (self .destination )
126234 self .destination .unlink ()
127235
128236
129237class Process ():
238+ """A Process is a collection of FunctionBlocks in which I/O are linked.
239+ FunctionBlocks in a Process gets executed sequentially in the order given by the FunctionBlock priority.
240+ The priority takes places by the order of function_blocks in the dictionary.
241+ Such order can be adjusted by reordering elements in the dictionary.
242+ """
130243 function_blocks = None
131244
132245 def __init__ (self ):
133246 self .function_blocks = {}
134247
135248 def add_function_block (self , function_block ):
249+ """Adds a function block to the process.
250+
251+ Args:
252+ function_block (FunctionBlock): the function block to be added.
253+ """
136254 self .function_blocks [function_block .name ] = function_block
137255
138256 def remove_function_block (self , function_block ):
257+ """Removes a function block from the process.
258+
259+ Args:
260+ function_block (FunctionBlock): the function block to be removed.
261+ """
139262 del self .function_blocks [function_block .name ]
140263
141264 def do (self ):
265+ """Executed the FunctionBlocks.
266+ Before to call a function block, all its Inputs are gethered by the linked outputs.
267+ If the input is not linked, the corresponding parameter takes the default value, whether available.
268+ The function block gets executed if all the parameters are available.
269+ Once the function block is executed, the results are assigned to its Outputs.
270+ """
142271 execution_priority = 0
143272 for function_block in self .function_blocks .values ():
144273 parameters = {}
0 commit comments