94 lines
3.3 KiB
Python
94 lines
3.3 KiB
Python
import ch.psi.pshell.device.Startable as Startable
|
|
import traceback
|
|
|
|
class StreamListener (DeviceListener):
|
|
def __init__(self, merger):
|
|
self.merger = merger
|
|
def onCacheChanged(self, device, value, former, timestamp, valueChange):
|
|
self.merger.update()
|
|
|
|
|
|
class StreamMerger(DeviceBase, Readable):
|
|
def __init__(self, name, st1, st2):
|
|
DeviceBase.__init__(self, name)
|
|
self.st1=st1
|
|
self.st2=st2
|
|
self.pulseId = -1
|
|
self.v1= None
|
|
self.v2= None
|
|
self.initialize()
|
|
self.running=False
|
|
self.listener = StreamListener(self)
|
|
self.setComponents([st1,st2])
|
|
|
|
|
|
def doUpdate(self):
|
|
try:
|
|
while True:
|
|
has_more_1 = has_more_2 = False
|
|
if (self.v1 is None) or ((self.v1 is not None) and (self.v2 is not None) and (self.v1.pulseId < self.v2.pulseId)):
|
|
if self.st1.bufferCapacity>0:
|
|
tm_value = self.st1.popBuffer()
|
|
self.v1 = None if tm_value is None else tm_value.value
|
|
has_more_1 = (v1 is not None)
|
|
else:
|
|
self.v1 = self.st1.take()
|
|
if (self.v2 is None) or ((self.v1 is not None) and (self.v2 is not None) and (self.v1.pulseId > self.v2.pulseId)):
|
|
if self.st2.bufferCapacity>0:
|
|
tm_value = self.st2.popBuffer()
|
|
self.v2 = None if tm_value is None else tm_value.value
|
|
has_more_2 = (v2 is not None)
|
|
else:
|
|
self.v2 = self.st2.take()
|
|
if ((self.v1 is not None) and (self.v2 is not None) and (self.v1.pulseId == self.v2.pulseId)):
|
|
if self.v1.pulseId > self.pulseId:
|
|
keys=self.v1.keys()
|
|
keys.addAll(self.v2.keys())
|
|
values=self.v1.values()
|
|
values.addAll(self.v2.values())
|
|
self.pulseId = self.v1.pulseId
|
|
self.values, self.keys = values, keys
|
|
self.setCache(values, None)
|
|
self.v1=self.v2=None
|
|
else:
|
|
if (not has_more_1) and (not has_more_2):
|
|
break
|
|
except Exception, ex:
|
|
print >> sys.stderr, traceback.format_exc()
|
|
def doSetMonitored(self,value):
|
|
if (value):
|
|
self.st1.addListener(self.listener)
|
|
self.st2.addListener(self.listener)
|
|
|
|
else:
|
|
self.st1.removeListener(self.listener)
|
|
self.st2.removeListener(self.listener)
|
|
|
|
def doClose(self):
|
|
self.doSetMonitored(False)
|
|
|
|
def getReadables(self):
|
|
ret = list(self.st1.children + self.st2.children)
|
|
ret = [item for item in ret if type(item)!=Stream.PidReader]
|
|
return [self.st1.getPidReader(),] + ret
|
|
|
|
def read(self):
|
|
return self.pulseId
|
|
|
|
def start(self):
|
|
if not self.st1.isStarted():
|
|
self.st1.start()
|
|
if not self.st2.isStarted():
|
|
self.st2.start()
|
|
|
|
def stop(self):
|
|
if self.st1.isStarted():
|
|
self.st1.stop()
|
|
if self.st2.isStarted():
|
|
self.st2.stop()
|
|
|
|
def isStarted(self):
|
|
return self.st1.isStarted() and self.st2.isStarted()
|
|
|
|
#TODO: Readable children devices
|