Repository URL to install this package:
|
Version:
2:2.1.3 ▾
|
# Copyright (c) 2015 Ultimaker B.V.
# Uranium is released under the terms of the AGPLv3 or higher.
from UM.Signal import Signal, SignalEmitter
from UM.Logger import Logger
from UM.PluginRegistry import PluginRegistry
## Manages all available output devices and the plugin objects used to create them.
#
# This class is intended as the main entry point for anything relating to file saving.
# For the most basic usage, call getActiveDevice() to get an output device, then
# call OutputDevice::requestWrite() on the returned object.
#
# Active Device
# -------------
#
# The active device by default is determined based on the priority of individual
# OutputDevice instances when there is more than one OutputDevice available. When
# adding a device, the active device will be updated with the highest priority device.
# Should there be two devices with the same priority the active device will be the first
# device encountered with that priority.
#
# Calling setActiveDevice() will override this behaviour and instead force the active
# device to the specified device. This active device will not change when a new device
# is added or removed, but it will revert back to the default behaviour if the active
# device is removed. Call resetActiveDevice() to reset the active device to the default
# behaviour based on priority.
#
# OutputDevicePlugin and OutputDevice creation/removal
# ----------------------------------------------------
#
# Each instance of an OutputDevicePlugin is meant as an OutputDevice creation object.
# Subclasses of OutputDevicePlugin are meant to perform device lookup and listening
# for events like device hot-plugging. When a new device has been detected, the plugin
# class should create an instance of an OutputDevice subclass and add it to this
# manager class using addOutputDevice(). Similarly, if a device has been removed the
# OutputDevicePlugin is expected to call removeOutputDevice() to remove the proper
# device.
#
class OutputDeviceManager(SignalEmitter):
def __init__(self):
super().__init__()
self._output_devices = {}
self._plugins = {}
self._active_device = None
self._active_device_override = False
self._write_in_progress = False
PluginRegistry.addType("output_device", self.addOutputDevicePlugin)
## Emitted whenever a registered device emits writeStarted.
#
# \sa OutputDevice::writeStarted
writeStarted = Signal()
## Emitted whenever a registered device emits writeProgress.
#
# \sa OutputDevice::writeProgress
writeProgress = Signal()
## Emitted whenever a registered device emits writeFinished.
#
# \sa OutputDevice::writeFinished
writeFinished = Signal()
## Emitted whenever a registered device emits writeError.
#
# \sa OutputDevice::writeError
writeError = Signal()
## Emitted whenever a registered device emits writeSuccess.
#
# \sa OutputDevice::writeSuccess
writeSuccess = Signal()
## Get a list of all registered output devices.
#
# \return \type{list} A list of all registered output devices.
def getOutputDevices(self):
return self._output_devices.values()
## Get a list of all IDs of registered output devices.
#
# \return \type{list} A list of all registered output device ids.
def getOutputDeviceIds(self):
return self._output_devices.keys()
## Get an output device by ID.
#
# \param device_id The ID of the device to retrieve.
# \return \type{OutputDevice} The output device corresponding to the ID or None if not found.
def getOutputDevice(self, device_id):
return self._output_devices.get(device_id, None)
## Emitted whenever an output device is added or removed.
outputDevicesChanged = Signal()
## Add and register an output device.
#
# \param \type{OutputDevice} The output device to add.
#
# \note Does nothing if a device with the same ID as the passed device was already added.
def addOutputDevice(self, device):
if device.getId() in self._output_devices:
Logger.log("i", "Output Device %s already added", device.getId())
return
self._output_devices[device.getId()] = device
device.writeStarted.connect(self.writeStarted)
device.writeProgress.connect(self.writeProgress)
device.writeFinished.connect(self.writeFinished)
device.writeError.connect(self.writeError)
device.writeSuccess.connect(self.writeSuccess)
self.outputDevicesChanged.emit()
if not self._active_device or not self._active_device_override:
self._active_device = self._findHighestPriorityDevice()
self.activeDeviceChanged.emit()
## Remove a registered device by ID
#
# \param device_id The ID of the device to remove.
#
# \note This does nothing if the device_id does not correspond to a registered device.
def removeOutputDevice(self, device_id):
if device_id not in self._output_devices:
return
device = self._output_devices[device_id]
del self._output_devices[device_id]
device.writeStarted.disconnect(self.writeStarted)
device.writeProgress.disconnect(self.writeProgress)
device.writeFinished.disconnect(self.writeFinished)
device.writeError.disconnect(self.writeError)
device.writeSuccess.disconnect(self.writeSuccess)
self.outputDevicesChanged.emit()
if self._active_device.getId() == device_id:
self._write_in_progress = False
self.resetActiveDevice()
## Emitted whenever the active device changes.
activeDeviceChanged = Signal()
## Get the active device.
def getActiveDevice(self):
return self._active_device
## Set the active device.
#
# \param device_id The ID of the device to set as active device.
#
# \note This does nothing if the device_id does not correspond to a registered device.
# \note This will override the default active device selection behaviour.
def setActiveDevice(self, device_id):
if device_id not in self._output_devices:
return
if not self._active_device or self._active_device.getId() != device_id:
self._active_device = self.getOutputDevice(device_id)
self._write_in_progress = False
self._active_device_override = True
self.activeDeviceChanged.emit()
## Reset the active device to the default device.
def resetActiveDevice(self):
self._active_device = self._findHighestPriorityDevice()
self._active_device_override = False
self._write_in_progress = False
self.activeDeviceChanged.emit()
## Add an OutputDevicePlugin instance.
#
# \param \type{OutputDevicePlugin} The plugin to add.
#
# \note This does nothing if the plugin was already added.
def addOutputDevicePlugin(self, plugin):
if plugin.getPluginId() in self._plugins:
Logger.log("i", "Output Device Plugin %s was already added.", plugin.getPluginId())
return
self._plugins[plugin.getPluginId()] = plugin
try:
plugin.start()
except Exception as e:
Logger.log("e", "Exception starting plugin %s: %s", plugin.getPluginId(), repr(e))
## Remove an OutputDevicePlugin by ID.
#
# \param plugin_id The ID of the plugin to remove.
#
# \note This does nothing if the specified plugin_id was not found.
def removeOutputDevicePlugin(self, plugin_id):
Logger.log("d", "Remove output device plugin %s", plugin_id)
if plugin_id not in self._plugins:
return
try:
self._plugins[plugin_id].stop()
except Exception as e:
Logger.log("e", "Exception stopping plugin %s: %s", plugin_id, repr(e))
del self._plugins[plugin_id]
## Get an OutputDevicePlugin by plugin ID
#
# \param plugin_id The ID of the plugin to retrieve
#
# \return The plugin corresponding to the specified ID or None if it was not found.
def getOutputDevicePlugin(self, plugin_id):
return self._plugins.get(plugin_id, None)
## private:
def _findHighestPriorityDevice(self):
device = None
for key, value in self._output_devices.items():
if not device or value.getPriority() > device.getPriority():
device = value
return device