Example #1
0
 def deInitialize():
     """
     Deinitialize the active application such that the filters are in CONSTRUCTED state
     :return:
     """
     assertMainThread()
     if Application.activeApplication is None:
         raise NexTRuntimeError("No active application to initialize")
     MethodInvoker(Application.activeApplication.stop, Qt.DirectConnection)
     MethodInvoker(Application.activeApplication.close, Qt.DirectConnection)
     MethodInvoker(Application.activeApplication.deinit,
                   Qt.DirectConnection)
Example #2
0
    def activeAppStateChange(self, newState):
        """
        Called when the active application changes its state.

        :param newState: the new application's state (see FilterState)
        :return:
        """
        assertMainThread()
        if newState == FilterState.CONSTRUCTED:
            self.actActivate.setEnabled(True)
        else:
            self.actActivate.setEnabled(False)
        if newState == FilterState.ACTIVE:
            if self._waitForOpenState is not None:
                app, pbfile, startPlay = self._waitForOpenState
                self._waitForOpenState = None
                if app == Application.activeApplication.getApplication(
                ).getName():
                    pbsrv = Services.getService("PlaybackControl")
                    if startPlay:
                        pbsrv.playbackPaused.connect(self._singleShotPlay)
                        QTimer.singleShot(2000, self._disconnectSingleShotPlay)
                    MethodInvoker(pbsrv.browser.setActive, Qt.QueuedConnection,
                                  pbfile)
            self.actDeactivate.setEnabled(True)
            self.actSaveWithGuiState.setEnabled(False)
        else:
            self.actDeactivate.setEnabled(False)
            self.actSaveWithGuiState.setEnabled(True)
Example #3
0
    def registerThread(self):
        """
        This slot shall be called from each activated nexxT thread with a direct connection.

        :return:
        """
        t = QThread.currentThread()
        logger.internal("registering thread %s", t.objectName())
        with self._lockThreadSpecific:
            if not t in self._threadSpecificProfiling:
                self._threadSpecificProfiling[t] = ThreadSpecificProfItem()
                self._threadSpecificProfiling[t].timer = QTimer(
                    parent=self.sender())
                self._threadSpecificProfiling[t].timer.timeout.connect(
                    self._generateRecord, Qt.DirectConnection)
                self._threadSpecificProfiling[t].timer.setInterval(
                    int(ThreadSpecificProfItem.THREAD_PROFILING_PERIOD_SEC *
                        1e3))
                self.stopTimers.connect(
                    self._threadSpecificProfiling[t].timer.stop)
                self.startTimers.connect(
                    self._threadSpecificProfiling[t].timer.start)
                if self._loadMonitoringEnabled:
                    self._threadSpecificProfiling[t].timer.start()

            tmain = QCoreApplication.instance().thread()
            if self._mi is None and not tmain in self._threadSpecificProfiling:
                self._mi = MethodInvoker(
                    dict(object=self, method="registerThread", thread=tmain),
                    Qt.QueuedConnection)
Example #4
0
 def setSequenceWrapper(filename):
     assertMainThread()
     if Application.activeApplication is None:
         return
     if Application.activeApplication.getState() not in [FilterState.ACTIVE, FilterState.OPENED]:
         return
     if QDir.match(nameFilters, pathlib.Path(filename).name):
         logger.debug("setSequence %s", filename)
         if Application.activeApplication.getState() == FilterState.ACTIVE:
             Application.activeApplication.stop()
         MethodInvoker(dict(object=playbackDevice, method="setSequence"), Qt.QueuedConnection, filename)
         Application.activeApplication.start()
         logger.debug("setSequence done")
     else:
         logger.debug("%s does not match filters: %s", filename, nameFilters)
         MethodInvoker(dict(object=playbackDevice, method="setSequence"), Qt.QueuedConnection, None)
Example #5
0
    def setupConnections(self, playbackDevice, nameFilters):
        """
        Sets up signal/slot connections between this view/controller instance and the given playbackDevice. This
        function is thread safe and shall be called by a direct QT connection.
        It is intended, that this function is called in the onOpen(...) method of a filter. It expects playbackDevice
        to provide the following slots:

        - startPlayback() (starts generating DataSamples)
        - pausePlayback() (pause mode, stop generating DataSamples)
        - stepForward(QString stream) (optional; in case given, a single step operation shall be performed.
            if stream is not None, the playback shall stop when receiving the next data sample
            of stream; otherwise the playback shall proceed to the next data sample of any stream)
        - stepBackward(QString stream) (optional; see stepForward)
        - seekBeginning(QString stream) (optional; goes to the beginning of the sequence)
        - seekEnd() (optional; goes to the end of the stream)
        - seekTime(qint64) (optional; goes to the specified time stamp)
        - setSequence(QString) (optional; opens the given sequence)
        - setTimeFactor(float) (optional; sets the playback time factor, factor > 0)

        It expects playbackDevice to provide the following signals (all signals are optional):

        - sequenceOpened(QString filename, qint64 begin, qint64 end, QStringList streams)
        - currentTimestampChanged(qint64 currentTime)
        - playbackStarted()
        - playbackPaused()
        - timeRatioChanged(float)

        :param playbackDevice: a QObject providing the aforementioned signals and slots
        :param nameFilters: a QStringList providing information about suported fileextensions (e.g. ["*.avi", "*.mp4"])
        :return:
        """
        with QMutexLocker(self._mutex):
            for devid in self._registeredDevices:
                if self._registeredDevices[devid]["object"] is playbackDevice:
                    raise NexTRuntimeError("Trying to register a playbackDevice object twice.")

            proxy = PlaybackDeviceProxy(self, playbackDevice, nameFilters)
            featureset = proxy.featureSet()

            for feature in ["stepForward", "stepBackward", "seekTime", "seekBeginning", "seekEnd",
                            "setTimeFactor", "startPlayback", "pausePlayback"]:
                signal = getattr(self, "_" + feature)
                slot = getattr(proxy, feature, None)
                if slot is not None:
                    signal.connect(slot)

            for feature in ["sequenceOpened", "currentTimestampChanged", "playbackStarted", "playbackPaused",
                            "timeRatioChanged"]:
                slot = getattr(self, "_" + feature)
                signal = getattr(proxy, feature, None)
                if signal is not None:
                    signal.connect(slot, Qt.UniqueConnection)

            self._registeredDevices[self._deviceId] = dict(object=playbackDevice,
                                                           featureset=featureset,
                                                           nameFilters=nameFilters,
                                                           proxy=proxy)
            self._deviceId += 1
            MethodInvoker(dict(object=self, method="_updateFeatureSet", thread=mainThread()), Qt.QueuedConnection)
Example #6
0
 def initialize():
     """
     Initialize the active application such that the filters are active.
     :return:
     """
     assertMainThread()
     if Application.activeApplication is None:
         raise NexTRuntimeError("No active application to initialize")
     # make sure that the application is re-created before initializing it
     # this is needed to synchronize the properties, etc.
     MethodInvoker(
         Application.activeApplication.getApplication().getConfiguration().
         activate, Qt.DirectConnection,
         Application.activeApplication.getApplication().getName())
     MethodInvoker(Application.activeApplication.init, Qt.DirectConnection)
     MethodInvoker(Application.activeApplication.open, Qt.DirectConnection)
     MethodInvoker(Application.activeApplication.start, Qt.DirectConnection)
Example #7
0
 def createFilterAndUpdate(self, immediate=True):
     """
     Creates the filter, performs init() operation and updates the port information.
     :return: None
     """
     if immediate:
         self._createFilterAndUpdate()
         self._createFilterAndUpdatePending = None
     elif self._createFilterAndUpdatePending is None:
         self._createFilterAndUpdatePending = MethodInvoker(
             dict(object=self, method="_createFilterAndUpdate"),
             Qt.QueuedConnection)
Example #8
0
 def createFilterAndUpdate(self, immediate=True):
     """
     Creates the filter, performs init() operation and updates the port information.
     :return: None
     """
     # TODO is it really a good idea to use queued connections for dynamic port changes?
     #      maybe there is a better way to prevent too many calls to _createFilterAndUpdate
     if immediate:
         self._createFilterAndUpdate()
         self._createFilterAndUpdatePending = None
     elif self._createFilterAndUpdatePending is None:
         self._createFilterAndUpdatePending = MethodInvoker(dict(object=self, method="_createFilterAndUpdate"),
                                                            Qt.QueuedConnection)
Example #9
0
    def appActivated(self, name, app):  # pylint: disable=unused-argument
        """
        Called when the application is activated.

        :param name: the application name
        :param app: An ActiveApplication instance.
        :return:
        """
        assertMainThread()
        if app is not None:
            self.activeAppStateChange(app.getState())
            app.stateChanged.connect(self.activeAppStateChange)
            if self._waitForActivated == app.getApplication():
                MethodInvoker(self.activate, Qt.QueuedConnection)
        else:
            self.actActivate.setEnabled(False)
            self.actDeactivate.setEnabled(False)
        self._waitForActivated = None
Example #10
0
    def removeConnections(self, playbackDevice):
        """
        unregisters the given playbackDevice and disconnects all. It is intended that this function is called in the
        onClose(...) method of a filter.

        :param playbackDevice: the playback device to be unregistered.
        :return: None
        """
        with QMutexLocker(self._mutex):
            found = []
            for devid in self._registeredDevices:
                if self._registeredDevices[devid]["object"] is playbackDevice:
                    found.append(devid)
            if len(found) > 0:
                for devid in found:
                    del self._registeredDevices[devid]
                logger.debug("disconnected connections of playback device. number of devices left: %d",
                             len(self._registeredDevices))
                MethodInvoker(dict(object=self, method="_updateFeatureSet", thread=mainThread()), Qt.QueuedConnection)
Example #11
0
def startNexT(cfgfile, active, execScripts, execCode, withGui):
    """
    Starts next with the given config file and activates the given application.
    :param cfgfile: path to config file
    :param active: active application (if None, the first application in the config will be used)
    :return: None
    """
    logger.debug("Starting nexxT...")
    config = Configuration()
    lcl = QLocale.system()
    lcl.setNumberOptions(QLocale.c().numberOptions())
    QLocale.setDefault(lcl)
    if withGui:
        app = QApplication() if QApplication.instance() is None else QApplication.instance()
        app.setWindowIcon(QIcon(":icons/nexxT.svg"))
        app.setOrganizationName("nexxT")
        app.setApplicationName("nexxT")
        setupGuiServices(config)
    else:
        app = QCoreApplication() if QCoreApplication.instance() is None else QCoreApplication.instance()
        app.setOrganizationName("nexxT")
        app.setApplicationName("nexxT")
        setupConsoleServices(config)

    if cfgfile is not None:
        ConfigFileLoader.load(config, cfgfile)
    if withGui:
        mainWindow = Services.getService("MainWindow")
        mainWindow.restoreState()
        mainWindow.show()
        # the reference will still be held by the service, but here we don't need it anymore
        del mainWindow
    if active is not None:
        config.activate(active)
        # pylint: disable=unused-variable
        # need to hold the reference of this until the method is called
        i2 = MethodInvoker(dict(object=Application, method="initialize", thread=app.thread()),
                           MethodInvoker.IDLE_TASK) # pylint: disable=unused-variable
        waitForSignal(config.appActivated)
        if Application.activeApplication.getState() != FilterState.ACTIVE:
            waitForSignal(Application.activeApplication.stateChanged, lambda s: s == FilterState.ACTIVE)
        logger.info("done")

    def cleanup():
        logger.debug("cleaning up loaded services")
        Services.removeAll()
        logger.debug("cleaning up loaded plugins")
        for v in ("last_traceback", "last_type", "last_value"):
            if hasattr(sys, v):
                del sys.__dict__[v]
        #PluginManager.singleton().unloadAll()
        logger.debug("cleaning up complete")

    code_globals = {}
    for c in execCode:
        logger.info("Executing code '%s'", c)
        # note that exec is used intentionally here to provide the user with scripting posibilities
        exec(compile(c, "<string>", 'exec'), code_globals) # pylint: disable=exec-used
        logger.debug("Executing code done")

    for s in execScripts:
        logger.info("Executing script '%s'", s)
        with open(s) as fscript:
            # note that exec is used intentionally here to provide the user with scripting possibilities
            exec(compile(fscript.read(), s, 'exec'), code_globals)  # pylint: disable=exec-used
        logger.debug("Executing script done")

    res = app.exec_()
    logger.debug("closing config")
    config.close()
    cleanup()

    logger.internal("app.exec_ returned")

    return res
Example #12
0
def execute_0():
    """
    Creates a new application with an app and a composite filter and saves it to a file; finally activate the
    created app.
    :return:
    """
    logger.info("execute_0:begin")

    cfg = Services.getService("Configuration")

    # create a new configuration with a composite graph and an application
    execute_0.i = MethodInvoker(cfg.newConfig, Qt.QueuedConnection,
                                "basicworkflow.json")
    waitForSignal(cfg.configuration().configNameChanged)

    # create simple composite filter
    cfg.configuration().renameComposite(
        cfg.configuration().addNewCompositeFilter(), "composite")
    comp = cfg.configuration().compositeFilterByName("composite")
    node = comp.getGraph().addNode(library="pyfile://./SimpleStaticFilter.py",
                                   factoryFunction="SimpleStaticFilter")
    idx = _getIndex(cfg.model, ["composite", "composite", node, "sleep_time"])
    cfg.model.setData(idx.siblingAtColumn(1), 0.01, Qt.EditRole)

    execute_0.i = MethodInvoker(comp.getGraph().addDynamicInputPort,
                                Qt.QueuedConnection, "CompositeOutput", "out")
    waitForSignal(comp.getGraph().dynInputPortAdded)
    execute_0.i = MethodInvoker(comp.getGraph().addDynamicOutputPort,
                                Qt.QueuedConnection, "CompositeInput", "in")
    waitForSignal(comp.getGraph().dynOutputPortAdded)
    comp.getGraph().addConnection("CompositeInput", "in", node, "inPort")
    comp.getGraph().addConnection(node, "outPort", "CompositeOutput", "out")

    # create simple application (live/recorder)
    cfg.configuration().renameApp(cfg.configuration().addNewApplication(),
                                  "myApp")
    app = cfg.configuration().applicationByName("myApp")
    import nexxT
    if nexxT.useCImpl:
        src = app.getGraph().addNode(
            library="entry_point://tests.nexxT.CSimpleSource",
            factoryFunction="entry_point")
    else:
        src = app.getGraph().addNode(
            library="pyfile://./SimpleStaticFilter.py",
            factoryFunction="SimpleSource")
    src2 = app.getGraph().addNode(library="pyfile://./SimpleStaticFilter.py",
                                  factoryFunction="SimpleSource")
    idx = _getIndex(cfg.model, ["apps", "myApp", src, "frequency"])
    cfg.model.setData(idx.siblingAtColumn(1), 10.0, Qt.EditRole)
    idx = _getIndex(cfg.model, ["apps", "myApp", src2, "frequency"])
    cfg.model.setData(idx.siblingAtColumn(1), 2.0, Qt.EditRole)
    idx = _getIndex(cfg.model, ["apps", "myApp", src2, "log_tr"])
    cfg.model.setData(idx.siblingAtColumn(1), False, Qt.EditRole)

    flt = app.getGraph().addNode(library=comp, factoryFunction="compositeNode")
    app.getGraph().addConnection(src, "outPort", flt, "in")

    # add a recorder
    rec = app.getGraph().addNode(library="pymod://nexxT.filters.hdf5",
                                 factoryFunction="Hdf5Writer")
    execute_0.i = MethodInvoker(app.getGraph().addDynamicInputPort,
                                Qt.QueuedConnection, rec, "stream1")
    waitForSignal(app.getGraph().dynInputPortAdded)
    execute_0.i = MethodInvoker(app.getGraph().addDynamicInputPort,
                                Qt.QueuedConnection, rec, "stream2")
    waitForSignal(app.getGraph().dynInputPortAdded)
    app.getGraph().addConnection(src, "outPort", rec, "stream1")
    app.getGraph().addConnection(src2, "outPort", rec, "stream2")

    # assign threads
    app.getGraph().getMockup(src).propertyCollection().getChildCollection(
        "_nexxT").setProperty("thread", "source-thread")
    app.getGraph().getMockup(src2).propertyCollection().getChildCollection(
        "_nexxT").setProperty("thread", "source2-thread")
    app.getGraph().getMockup(rec).propertyCollection().getChildCollection(
        "_nexxT").setProperty("thread", "rec-thread")

    # create another application (playback)
    # hdf5 reader
    cfg.configuration().renameApp(cfg.configuration().addNewApplication(),
                                  "pbApp")
    app = cfg.configuration().applicationByName("pbApp")
    pb = app.getGraph().addNode(library="pymod://nexxT.filters.hdf5",
                                factoryFunction="Hdf5Reader",
                                suggestedName="player")
    assert pb == "player"
    execute_0.i = MethodInvoker(app.getGraph().addDynamicOutputPort,
                                Qt.QueuedConnection, pb, "stream1")
    waitForSignal(app.getGraph().dynOutputPortAdded)
    execute_0.i = MethodInvoker(app.getGraph().addDynamicOutputPort,
                                Qt.QueuedConnection, pb, "stream2")
    waitForSignal(app.getGraph().dynOutputPortAdded)
    # 2 filters
    flt1 = app.getGraph().addNode(library="pyfile://./SimpleStaticFilter.py",
                                  factoryFunction="SimpleStaticFilter",
                                  suggestedName="flt1")
    assert flt1 == "flt1"
    idx = _getIndex(cfg.model, ["apps", "pbApp", "flt1", "sleep_time"])
    cfg.model.setData(idx.siblingAtColumn(1), 0.01, Qt.EditRole)
    idx = _getIndex(cfg.model, ["apps", "pbApp", "flt1", "log_rcv"])
    cfg.model.setData(idx.siblingAtColumn(1), True, Qt.EditRole)
    idx = _getIndex(cfg.model, ["apps", "pbApp", "flt1", "log_prefix"])
    cfg.model.setData(idx.siblingAtColumn(1), "(flt1) ", Qt.EditRole)

    flt2 = app.getGraph().addNode(library="pyfile://./SimpleStaticFilter.py",
                                  factoryFunction="SimpleStaticFilter",
                                  suggestedName="flt2")
    assert flt2 == "flt2"
    idx = _getIndex(cfg.model, ["apps", "pbApp", "flt2", "sleep_time"])
    cfg.model.setData(idx.siblingAtColumn(1), 0.01, Qt.EditRole)
    idx = _getIndex(cfg.model, ["apps", "pbApp", "flt2", "log_rcv"])
    cfg.model.setData(idx.siblingAtColumn(1), True, Qt.EditRole)
    idx = _getIndex(cfg.model, ["apps", "pbApp", "flt2", "log_prefix"])
    cfg.model.setData(idx.siblingAtColumn(1), "(flt2) ", Qt.EditRole)

    app.getGraph().addConnection("player", "stream1", "flt1", "inPort")
    app.getGraph().addConnection("player", "stream2", "flt2", "inPort")

    # save application
    execute_0.i = MethodInvoker(cfg.saveConfig, Qt.QueuedConnection)
    waitForSignal(cfg.configuration().configNameChanged)

    # change active app
    execute_1.i = MethodInvoker(cfg.changeActiveApp, Qt.QueuedConnection,
                                "myApp")
    waitForSignal(cfg.configuration().appActivated)

    # activate
    execute_1.i = MethodInvoker(cfg.activate, Qt.QueuedConnection)
    waitForSignal(cfg.configuration().appActivated)
    if app.activeApplication.getState() != FilterState.ACTIVE:
        waitForSignal(app.activeApplication.stateChanged,
                      lambda s: s == FilterState.ACTIVE)
    logger.info("execute_0:end")
Example #13
0
def execute_2():
    logger.info("execute_2:begin")
    cfg = Services.getService("Configuration")
    pbc = Services.getService("PlaybackControl")

    app = cfg.configuration().applicationByName("pbApp")

    logger.info("app activated")
    execute_2.i = MethodInvoker(pbc.setSequence, Qt.QueuedConnection,
                                glob.glob("./*.h5")[0])
    _, tbegin, tend, _ = waitForSignal(pbc.sequenceOpened)

    execute_2.i = MethodInvoker(pbc.startPlayback, Qt.QueuedConnection)
    waitForSignal(pbc.playbackStarted)
    waitForSignal(pbc.playbackPaused)
    logger.info("played")

    execute_2.i = MethodInvoker(pbc.seekBeginning, Qt.QueuedConnection)
    waitForSignal(pbc.currentTimestampChanged)
    logger.info("seekBeginning")

    for i in range(10):
        execute_2.i = MethodInvoker(pbc.stepForward, Qt.QueuedConnection, None)
        waitForSignal(pbc.playbackPaused)
        logger.info("stepForward[None]")

    for i in range(10):
        execute_2.i = MethodInvoker(pbc.stepForward, Qt.QueuedConnection,
                                    "stream1")
        waitForSignal(pbc.playbackPaused)
        logger.info("stepForward[stream1]")

    for i in range(2):
        execute_2.i = MethodInvoker(pbc.stepForward, Qt.QueuedConnection,
                                    "stream2")
        waitForSignal(pbc.playbackPaused)
        logger.info("stepForward[stream2]")

    execute_2.i = MethodInvoker(pbc.seekTime, Qt.QueuedConnection,
                                (tbegin + tend) // 2)
    waitForSignal(pbc.currentTimestampChanged)
    logger.info("seekTime")

    execute_2.i = MethodInvoker(pbc.seekEnd, Qt.QueuedConnection)
    waitForSignal(pbc.currentTimestampChanged)
    logger.info("seekEnd")

    for i in range(10):
        execute_2.i = MethodInvoker(pbc.stepBackward, Qt.QueuedConnection,
                                    None)
        waitForSignal(pbc.playbackPaused)
        logger.info("stepBackward[None]")

    execute_2.i = MethodInvoker(pbc.seekTime, Qt.QueuedConnection,
                                tbegin - 1000000000)
    waitForSignal(pbc.currentTimestampChanged)
    logger.info("seekTimeBegin")

    execute_2.i = MethodInvoker(pbc.seekTime, Qt.QueuedConnection,
                                tend + 1000000000)
    waitForSignal(pbc.currentTimestampChanged)
    logger.info("seekTimeEnd")

    execute_2.i = MethodInvoker(QCoreApplication.quit, Qt.QueuedConnection)
    logger.info("execute_2:end")
Example #14
0
def execute_1():
    """
    after 3 seconds, deactivate and re-activate the app
    after 3 seconds, re-open and re-activate the app
    after 3 more seconds, quit
    :return:
    """
    logger.info("execute_1:begin")
    cfg = Services.getService("Configuration")
    rc = Services.getService("RecordingControl")

    logger.info("app activated")
    app = cfg.configuration().applicationByName("myApp")

    t = QTimer()
    t.setSingleShot(True)
    t.setInterval(3000)
    t.start()
    waitForSignal(t.timeout)

    execute_1.i = MethodInvoker(cfg.deactivate, Qt.QueuedConnection)
    waitForSignal(app.activeApplication.stateChanged,
                  lambda s: s == FilterState.CONSTRUCTED)
    logger.info("app deactivated")

    execute_1.i = MethodInvoker(cfg.activate, Qt.QueuedConnection)
    waitForSignal(cfg.configuration().appActivated)
    if app.activeApplication.getState() != FilterState.ACTIVE:
        waitForSignal(app.activeApplication.stateChanged,
                      lambda s: s == FilterState.ACTIVE)

    execute_1.i = MethodInvoker(rc.startRecording, Qt.QueuedConnection, ".")
    logger.info("app activated")

    t = QTimer()
    t.setSingleShot(True)
    t.setInterval(3000)
    t.start()
    waitForSignal(t.timeout)

    execute_1.i = MethodInvoker(cfg.deactivate, Qt.QueuedConnection)
    waitForSignal(app.activeApplication.stateChanged,
                  lambda s: s == FilterState.CONSTRUCTED)
    logger.info("app deactivated")

    # re-open this application
    execute_1.i = MethodInvoker(cfg.loadConfig, Qt.QueuedConnection,
                                "basicworkflow.json")
    waitForSignal(cfg.configuration().configNameChanged)
    logger.info("config loaded")

    # activate
    execute_1.i = MethodInvoker(cfg.changeActiveApp, Qt.QueuedConnection,
                                "myApp")
    waitForSignal(cfg.configuration().appActivated)
    execute_1.i = MethodInvoker(cfg.activate, Qt.QueuedConnection)
    waitForSignal(cfg.configuration().appActivated)
    if app.activeApplication.getState() != FilterState.ACTIVE:
        waitForSignal(app.activeApplication.stateChanged,
                      lambda s: s == FilterState.ACTIVE)
    logger.info("app activated")

    t = QTimer()
    t.setSingleShot(True)
    t.setInterval(3000)
    t.start()
    waitForSignal(t.timeout)

    execute_1.i = MethodInvoker(QCoreApplication.quit, Qt.QueuedConnection)
    logger.info("execute_1:end")
Example #15
0
 def _singleShotPlay(self):
     assertMainThread()
     pbsrv = Services.getService("PlaybackControl")
     MethodInvoker(pbsrv.startPlayback, Qt.QueuedConnection)
     self._disconnectSingleShotPlay()
Example #16
0
    def setupConnections(self, playbackDevice, nameFilters):
        """
        Sets up signal/slot connections between this view/controller instance and the given playbackDevice. This
        function is thread safe and shall be called by a direct QT connection.
        It is intended, that this function is called in the onOpen(...) method of a filter. It expects playbackDevice
        to provide the following slots:

        - startPlayback() (starts generating DataSamples)
        - pausePlayback() (pause mode, stop generating DataSamples)
        - stepForward(QString stream) (optional; in case given, a single step operation shall be performed.
                               if stream is not None, the playback shall stop when receiving the next data sample
                               of stream; otherwise the playback shall proceed to the next data sample of any stream)
        - stepBackward(QString stream) (optional; see stepForward)
        - seekBeginning(QString stream) (optional; goes to the beginning of the sequence)
        - seekEnd() (optional; goes to the end of the stream)
        - seekTime(QString QDateTime) (optional; goes to the specified time stamp)
        - setSequence(QString) (optional; opens the given sequence)
        - setTimeFactor(float) (optional; sets the playback time factor, factor > 0)

        It expects playbackDevice to provide the following signals (all signals are optional):

        - sequenceOpened(QString filename, QDateTime begin, QDateTime end, QStringList streams)
        - currentTimestampChanged(QDateTime currentTime)
        - playbackStarted()
        - playbackPaused()
        - timeRatioChanged(float)

        :param playbackDevice: a QObject providing the aforementioned signals and slots
        :param nameFilters: a QStringList providing information about suported fileextensions (e.g. ["*.avi", "*.mp4"])
        :return:
        """
        with QMutexLocker(self._mutex):
            for devid in self._registeredDevices:
                if self._registeredDevices[devid]["object"] is playbackDevice:
                    raise NexTRuntimeError("Trying to register a playbackDevice object twice.")

            if not self._startPlayback.connect(playbackDevice.startPlayback):
                raise NexTRuntimeError("cannot connect to slot startPlayback()")
            if not self._pausePlayback.connect(playbackDevice.pausePlayback):
                raise NexTRuntimeError("cannot connect to slot pausePlayback()")

            connections = [(self._startPlayback, playbackDevice.startPlayback),
                           (self._pausePlayback, playbackDevice.pausePlayback)]
            featureset = set(["startPlayback", "pausePlayback"])
            for feature in ["stepForward", "stepBackward", "seekTime", "seekBeginning", "seekEnd",
                            "setTimeFactor"]:
                signal = getattr(self, "_" + feature)
                slot = getattr(playbackDevice, feature, None)
                if slot is not None and signal.connect(slot, Qt.UniqueConnection):
                    featureset.add(feature)
                    connections.append((signal, slot))

            @handleException
            def setSequenceWrapper(filename):
                assertMainThread()
                if Application.activeApplication is None:
                    return
                if Application.activeApplication.getState() not in [FilterState.ACTIVE, FilterState.OPENED]:
                    return
                if QDir.match(nameFilters, pathlib.Path(filename).name):
                    logger.debug("setSequence %s", filename)
                    if Application.activeApplication.getState() == FilterState.ACTIVE:
                        Application.activeApplication.stop()
                    MethodInvoker(dict(object=playbackDevice, method="setSequence"), Qt.QueuedConnection, filename)
                    Application.activeApplication.start()
                    logger.debug("setSequence done")
                else:
                    logger.debug("%s does not match filters: %s", filename, nameFilters)
                    MethodInvoker(dict(object=playbackDevice, method="setSequence"), Qt.QueuedConnection, None)

            # setSequence is called only if filename matches the given filters
            if self._setSequence.connect(setSequenceWrapper, Qt.DirectConnection):
                featureset.add("setSequence")
                connections.append((self._setSequence, setSequenceWrapper))
            for feature in ["sequenceOpened", "currentTimestampChanged", "playbackStarted", "playbackPaused",
                            "timeRatioChanged"]:
                slot = getattr(self, "_" + feature)
                signal = getattr(playbackDevice, feature, None)
                if signal is not None and signal.connect(slot, Qt.UniqueConnection):
                    featureset.add(feature)
                    connections.append((signal, slot))

            self._registeredDevices[self._deviceId] = dict(object=playbackDevice,
                                                           featureset=featureset,
                                                           nameFilters=nameFilters,
                                                           connections=connections)
            self._deviceId += 1
            MethodInvoker(dict(object=self, method="_updateFeatureSet", thread=mainThread()), Qt.QueuedConnection)