121 lines
3.7 KiB
Python
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
|