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)
def setLaserConnectionParameters(self, ftpAddress, ftpPort, ftpRemotePath=""): locker = QMutexLocker(self.__mutex) self.__laserFTPAddress = ftpAddress self.__laserFTPPort = ftpPort self.__laserFTPRemotePath = ftpRemotePath
def RGBD_getXYZ(self): locker = QMutexLocker(self.mutex) print('not implemented') sys.exit(0) points = [] hState = {} bState = RoboCompGenericBase.TBaseState() return (points, hState, bState)
def getProperty(self, name): self._accessed = True with QMutexLocker(self._propertyMutex): if name not in self._properties: raise PropertyCollectionPropertyNotFound(name) p = self._properties[name] p.used = True return p.value
def markAllUnused(self): """ Mark all properties of the collection as unused (TODO: do we need recursion?) :return: None """ with QMutexLocker(self._propertyMutex): for n in self._properties: self._properties[n].used = False
def requestNewFortune(self, hostname, port): locker = QMutexLocker(self.mutex) self.hostName = hostname self.port = port if not self.isRunning(): self.start() else: self.cond.wakeOne()
def __setattr__(self, name, value): obj = object.__getattribute__(self, "_obj") if not obj: raise Exception("no object on proxy") methods = object.__getattribute__(self, "_methods") if name in methods: raise Exception("cannot set method on proxy") with QMutexLocker(object.__getattribute__(self, "_mutex")) as locker: setattr(obj, name, value)
def setupConnections(self, recordingDevice): """ 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 onStart(...) method of a filter. It expects recordingDevice to provide the following slots: - startRecording(str directory) (starts recording DataSamples) - stopRecording() (stop the recording) It expects recordingDevice to provide the following signals (all signals are optional): - statusUpdate(str file, float lengthInSeconds, int bytesWritten) - notifyError(str errorDescription) :param recordingDevice: a QObject providing the aforementioned signals and slots :return: """ with QMutexLocker(self._mutex): for devid in self._registeredDevices: if self._registeredDevices[devid]["object"] is recordingDevice: raise NexTRuntimeError( "Trying to register a playbackDevice object twice.") if not self._startRecording.connect( recordingDevice.startRecording): raise NexTRuntimeError( "cannot connect to slot startPlayback()") if not self._stopRecording.connect(recordingDevice.stopRecording): raise NexTRuntimeError( "cannot connect to slot pausePlayback()") connections = [ (self._startRecording, recordingDevice.startRecording), (self._stopRecording, recordingDevice.stopRecording) ] featureset = set() for feature in ["statusUpdate", "notifyError"]: slot = getattr(self, "_" + feature) signal = getattr(recordingDevice, 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=recordingDevice, featureset=featureset, connections=connections) logger.debug( "connected recording device. Current number of devices: %d", len(self._registeredDevices)) self._deviceId += 1 self._updateFeatureSet()
def update(self, dbg): # options ml = QMutexLocker(self.mutex) self.times = np.append(self.times, [time.perf_counter_ns()]) v = self.times >= self.times[-1] - self.history_time_ns self.times = self.times[v] self.gas = np.append(self.gas, [dbg.axisValues[2]])[v] self.brake = np.append(self.brake, [dbg.axisValues[3]])[v] self.clutch = np.append(self.clutch, [dbg.axisValues[4]])[v] self.sx = np.append(self.sx, [dbg.axisValues[0]])[v] self.sy = np.append(self.sy, [dbg.axisValues[1]])[v] self.calib = dbg.calib
def getPropertyDetails(self, name): """ returns the property details of the property identified by name. :param name: the property name :return: a Property instance """ with QMutexLocker(self._propertyMutex): if name not in self._properties: raise PropertyCollectionPropertyNotFound(name) p = self._properties[name] return p
def __getattribute__(self, name): if name == 'apply' or name == 'lock' or name == 'unlock': return object.__getattribute__(self, name) obj = object.__getattribute__(self, "_obj") if not obj: raise Exception("no object on proxy") methods = object.__getattribute__(self, "_methods") if name in methods: return methods[name] with QMutexLocker(object.__getattribute__(self, "_mutex")) as locker: return getattr(obj, name)
def updatePortInformation(self, otherInstance): """ Copy port information from another FilterEnvironment instance to this. :param otherInstance: FilterEnvironment instance :return: None """ with QMutexLocker(self._portMutex): oldIn = self.getAllInputPorts() oldOut = self.getAllOutputPorts() self._ports = [p.clone(self) for p in otherInstance.getAllInputPorts() + otherInstance.getAllOutputPorts()] self.setDynamicPortsSupported(*otherInstance.getDynamicPortsSupported()) self.emitPortInformationUpdated(oldIn, oldOut)
def getPort(self, portName, portType): """ Get port by name :param portName: the name of the port :param portType: either InputPort or OutputPort :return: port instance """ query = {InputPortInterface:"isInput", OutputPortInterface:"isOutput"} with QMutexLocker(self._portMutex): f = [p for p in self._ports if getattr(p, query[portType])() and p.name() == portName] if len(f) != 1: raise PortNotFoundError("<unknown>", portName, portType) return f[0]
def createFilter(self): """ Creates the filter for real usage. State is CONSTRUCTED. This function is thread safe and can be called from multiple threads. :return: None """ # called from threads res = FilterEnvironment(self._library, self._factoryFunction, self._propertyCollectionImpl) with QMutexLocker(self._portMutex): for p in self._ports: if p.dynamic(): res.addPort(p.clone(res)) return res
def removePort(self, port): """ Unregister a port of this filter :param port: instacne of InputPort or OutputPort :return: None """ with QMutexLocker(self._portMutex): logger.debug("remove port: %s", port) if useCImpl: for p in self._ports: if p.data() == port.data(): port = p self._ports.remove(port)
def render(self, centerX, centerY, scaleFactor, resultSize): locker = QMutexLocker(self.mutex) self.centerX = centerX self.centerY = centerY self.scaleFactor = scaleFactor self.resultSize = resultSize if not self.isRunning(): self.start(QThread.LowPriority) else: self.restart = True self.condition.wakeOne()
def saveDict(self): """ Save properties into a dictionary suited for json output. :return: dictionary with key/value pairs """ if self._accessed: res = OrderedDict() with QMutexLocker(self._propertyMutex): for n in sorted(self._properties): p = self._properties[n] res[n] = p.handler.toConfig(p.value) return res return self._loadedFromConfig
def add(self, other): ml = QMutexLocker(other.mutex) ml2 = QMutexLocker(self.mutex) self.times = np.append(self.times, other.times) self.gas = np.append(self.gas, other.gas) self.brake = np.append(self.brake, other.brake) self.clutch = np.append(self.clutch, other.clutch) self.sx = np.append(self.sx, other.sx) self.sy = np.append(self.sy, other.sy) self.calib = other.calib other.times = np.resize(other.times, (0, )) other.gas = np.resize(other.gas, (0, )) other.brake = np.resize(other.brake, (0, )) other.clutch = np.resize(other.clutch, (0, )) other.sx = np.resize(other.sx, (0, )) other.sy = np.resize(other.sy, (0, )) v = self.times >= self.times[-1] - self.history_time_ns self.times = self.times[v] self.gas = self.gas[v] self.brake = self.brake[v] self.clutch = self.clutch[v] self.sx = self.sx[v] self.sy = self.sy[v]
def defineProperty(self, name, defaultVal, helpstr, options=None, propertyHandler=None): """ Return the value of the given property, creating a new property if it doesn't exist. :param name: the name of the property :param defaultVal: the default value of the property. Note that this value will be used to determine the property's type. Currently supported types are string, int and float :param helpstr: a help string for the user :param options: a dict mapping string to qvariant (common options: min, max, enum) :param propertyHandler: a PropertyHandler instance, or None for automatic choice according to defaultVal :return: the current value of this property """ self._accessed = True checkIdentifier(name) if options is not None and propertyHandler is None and isinstance(options, PropertyHandler): propertyHandler = options options = None with QMutexLocker(self._propertyMutex): if options is not None and propertyHandler is not None: raise PropertyInconsistentDefinition( "Pass either options or propertyHandler to defineProperty but not both.") if options is None: options = {} if propertyHandler is None: propertyHandler = defaultHandler(defaultVal)(options) assert isinstance(propertyHandler, PropertyHandler) assert isinstance(options, dict) if propertyHandler.validate(defaultVal) != defaultVal: raise PropertyInconsistentDefinition("The validation of the default value must be the identity!") if not name in self._properties: self._properties[name] = Property(defaultVal, helpstr, propertyHandler) p = self._properties[name] if name in self._loadedFromConfig: l = self._loadedFromConfig[name] try: p.value = p.handler.validate(p.handler.fromConfig(l)) except Exception as e: raise PropertyParsingError("Error parsing property %s from %s (original exception: %s)" % (name, repr(l), str(e))) self.propertyAdded.emit(self, name) else: # the arguments to getProperty shall be consistent among calls p = self._properties[name] if p.defaultVal != defaultVal or p.helpstr != helpstr: raise PropertyInconsistentDefinition(name) if not isinstance(p.handler, type(propertyHandler)) or options != p.handler.options(): raise PropertyInconsistentDefinition(name) p.used = True return p.value
def deleteUnused(self): """ Delete properties marked as unused (TODO: do we need recursion?) :return: None """ if not self._accessed: # this function is only meaningful if something in the store has been used. return with QMutexLocker(self._propertyMutex): toDel = [] for n in self._properties: if not self._properties[n].used: toDel.append(n) for n in toDel: del self._properties[n] self.propertyRemoved.emit(self, n) self._loadedFromConfig.clear()
def _getDB(self): if self.threadSafety == self.SINGLE_CONNECTION: return self.dbConn # create a new connection for each thread with QMutexLocker(self.mutex): tid = QThread.currentThread() if not tid in self.dbs: # Our custom argument db = sqlite3.connect(self.filename) # might need to use self.filename if len(self.dbs) == 0: db.execute( "CREATE TABLE IF NOT EXISTS " "debug(date datetime, loggername text, filename, srclineno integer, " "func text, level text, msg text)") db.commit() self.dbs[tid] = db return self.dbs[tid]
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)
def setProperty(self, name, value): """ Set the value of a named property. :param name: property name :param value: the value to be set :return: None """ self._accessed = True with QMutexLocker(self._propertyMutex): if name not in self._properties: raise PropertyCollectionPropertyNotFound(name) p = self._properties[name] try: value = p.handler.validate(value) except Exception as e: raise PropertyParsingError("Error parsing property %s from %s (original exception: %s)" % (name, repr(value), str(e))) if value != p.value: p.value = value self.propertyChanged.emit(self, name)
def addPort(self, port): """ Register a port of this filter. :param port: instance of InputPort ot OutputPort :return: None """ if useCImpl: # make sure to make copies of the shared pointers port = copy.copy(port) with QMutexLocker(self._portMutex): assert self.state() in [FilterState.CONSTRUCTING, FilterState.CONSTRUCTED, FilterState.INITIALIZING] dynInSupported, dynOutSupported = self.getDynamicPortsSupported() if port.dynamic() and ((port.isInput() and not dynInSupported) or (port.isOutput() and not dynOutSupported)): raise DynamicPortUnsupported(port.name(), type(port)) for p in self._ports: if p.isInput() and port.isInput() and p.name() == port.name(): raise PortExistsError("<unknown>", port.name(), InputPortInterface) if p.isOutput() and port.isOutput() and p.name() == port.name(): raise PortExistsError("<unknown>", port.name(), OutputPortInterface) self._ports.append(port)
def removeConnections(self, recordingDevice): """ unregisters the given recordingDevice and disconnects all. It is intended that this function is called in the onStop(...) method of a filter. :param recordingDevice: the recording device to be unregistered. :return: None """ with QMutexLocker(self._mutex): found = [] for devid in self._registeredDevices: if self._registeredDevices[devid]["object"] is recordingDevice: found.append(devid) if len(found) > 0: for devid in found: for signal, slot in self._registeredDevices[devid][ "connections"]: signal.disconnect(slot) del self._registeredDevices[devid] logger.debug( "disconnected connections of recording device. number of devices left: %d", len(self._registeredDevices)) self._updateFeatureSet()
def _getOutputPorts(self, dynamic): with QMutexLocker(self._portMutex): return [p for p in self._ports if p.isOutput() and (p.dynamic() == dynamic or dynamic is None)]
def __repr__(self): with QMutexLocker(object.__getattribute__(self, "_mutex")) as locker: obj = object.__getattribute__(self, "_obj") return repr(obj)
def __nonzero__(self): with QMutexLocker(object.__getattribute__(self, "_mutex")) as locker: obj = object.__getattribute__(self, "_obj") return bool(obj)
def __call__(self, *args, **kwds): with QMutexLocker(self.mutex) as locker: return self.method(*args, **kwds)
def stop(self): with QMutexLocker(self.mutex): self._abort = True self.wait()