msspec_python3/msspec/msspecgui/dataflow/operator.py

121 lines
3.7 KiB
Python

# import plug
# from .dflow import DataFlow
from .plug import Plug
class Operator(object):
'''
an abstract operator that generates outputs from its inputs
'''
def __init__(self, data_flow, creator):
'''
Constructor
:param data_flow: the data_flow that will contain this operator
:type data_flow: DataFlow
:param creator: an instance of IOperatorCreator, the creator of this object (consider it as an object that stores informations that are common to all operators of this type).
:type creator: dataflow.ioperatorcreator.IOperatorCreator
'''
self._data_flow = data_flow
self._creator = creator
self._id = data_flow.get_new_operator_id()
self._input_plugs = {}
self._output_plugs = {}
for attr in self._creator.get_input_attributes():
data_type = self._data_flow.get_data_type(attr.type_name)
assert data_type is not None
p = Plug(attr, data_type, Plug.PlugSide.INPUT, self)
self._input_plugs[p.name] = p
for attr in self._creator.get_output_attributes():
data_type = self._data_flow.get_data_type(attr.type_name)
assert data_type is not None
p = Plug(attr, data_type, Plug.PlugSide.OUTPUT, self)
self._output_plugs[p.name] = p
@property
def name(self):
return '%s_%d' % (self._creator.get_operator_type_id(), self._id)
def get_input_plugs(self):
"""
:rtype: list(msspecgui.dataflow.Plug)
"""
return list(self._input_plugs.itervalues())
def get_output_plugs(self):
"""
:rtype: list(msspecgui.dataflow.Plug)
"""
return list(self._output_plugs.itervalues())
def get_plug(self, plug_name):
"""
:type plug_name: str
:rtype: msspecgui.dataflow.Plug
"""
if plug_name in self._input_plugs:
return self._input_plugs[plug_name]
if plug_name in self._output_plugs:
return self._output_plugs[plug_name]
@property
def wires(self):
"""
:return list(msspecgui.dataflow.Wire)
"""
wires = []
for p in self._input_plugs.itervalues():
if p.is_connected():
wires.append(p.incoming_wire)
for p in self._output_plugs.itervalues():
if p.is_connected():
for wire in p.outgoing_wires:
wires.append(wire)
return wires
def set_dirty(self):
"""
indicates that the output values of this operator are obsolete and need to be recomputed
"""
print("setting operator %d as dirty" % self.id)
for plug in self.get_output_plugs():
plug.set_dirty()
def update(self):
"""
compute this operator's output values from its input values
this method is supposed to be overriden in derived classes
"""
assert False # should be implemented in derived classes
def all_inputs_are_available(self):
for input_plug in self.get_input_plugs():
if not input_plug.value_is_available():
return False
return True
@property
def id(self):
"""
:rtype: int
"""
return self._id
@id.setter
def id(self, operator_id):
"""changes the unique identifier of this operator (use at your own risk)
:param int operator_id: the new unique identifier for this operator
"""
self._id = operator_id
@property
def creator(self):
return self._creator
@property
def data_flow(self):
return self._data_flow