1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2024-10-06 19:01:15 +01:00
workload-automation/wlauto/external/louie/plugin.py
2015-03-10 13:09:31 +00:00

109 lines
3.2 KiB
Python

"""Common plugins for Louie."""
from louie import dispatcher
from louie import error
def install_plugin(plugin):
cls = plugin.__class__
for p in dispatcher.plugins:
if p.__class__ is cls:
raise error.PluginTypeError(
'Plugin of type %r already installed.' % cls)
dispatcher.plugins.append(plugin)
def remove_plugin(plugin):
dispatcher.plugins.remove(plugin)
class Plugin(object):
"""Base class for Louie plugins.
Plugins are used to extend or alter the behavior of Louie
in a uniform way without having to modify the Louie code
itself.
"""
def is_live(self, receiver):
"""Return True if the receiver is still live.
Only called for receivers who have already been determined to
be live by default Louie semantics.
"""
return True
def wrap_receiver(self, receiver):
"""Return a callable that passes arguments to the receiver.
Useful when you want to change the behavior of all receivers.
"""
return receiver
class QtWidgetPlugin(Plugin):
"""A Plugin for Louie that knows how to handle Qt widgets
when using PyQt built with SIP 4 or higher.
Weak references are not useful when dealing with QWidget
instances, because even after a QWidget is closed and destroyed,
only the C++ object is destroyed. The Python 'shell' object
remains, but raises a RuntimeError when an attempt is made to call
an underlying QWidget method.
This plugin alleviates this behavior, and if a QWidget instance is
found that is just an empty shell, it prevents Louie from
dispatching to any methods on those objects.
"""
def __init__(self):
try:
import qt
except ImportError:
self.is_live = self._is_live_no_qt
else:
self.qt = qt
def is_live(self, receiver):
"""If receiver is a method on a QWidget, only return True if
it hasn't been destroyed."""
if (hasattr(receiver, 'im_self') and
isinstance(receiver.im_self, self.qt.QWidget)
):
try:
receiver.im_self.x()
except RuntimeError:
return False
return True
def _is_live_no_qt(self, receiver):
return True
class TwistedDispatchPlugin(Plugin):
"""Plugin for Louie that wraps all receivers in callables
that return Twisted Deferred objects.
When the wrapped receiver is called, it adds a call to the actual
receiver to the reactor event loop, and returns a Deferred that is
called back with the result.
"""
def __init__(self):
# Don't import reactor ourselves, but make access to it
# easier.
from twisted import internet
from twisted.internet.defer import Deferred
self._internet = internet
self._Deferred = Deferred
def wrap_receiver(self, receiver):
def wrapper(*args, **kw):
d = self._Deferred()
def called(dummy):
return receiver(*args, **kw)
d.addCallback(called)
self._internet.reactor.callLater(0, d.callback, None)
return d
return wrapper