Commit be3c39e6 authored by Dan Pascu's avatar Dan Pascu

Reduced the (call|run)_in_gui_thread overhead by a factor of 3

parent 1fc464f1
......@@ -2,6 +2,7 @@
from PyQt4.QtCore import QObject, QThread, QTimer
from PyQt4.QtGui import QApplication
from application.python.decorator import decorator, preserve_signature
from application.python.descriptor import classproperty
from application.python.types import Singleton
from functools import partial
from threading import Event
......@@ -17,16 +18,54 @@ class QSingleton(Singleton, type(QObject)):
"""A metaclass for making Qt objects singletons"""
def call_later(interval, function, *args, **kw):
QTimer.singleShot(int(interval*1000), lambda: function(*args, **kw))
def call_in_gui_thread(function, *args, **kw):
application = QApplication.instance()
if application.thread() is QThread.currentThread():
application = Application.instance
if QThread.currentThread() is Application.gui_thread:
return function(*args, **kw)
else:
application.postEvent(application, CallFunctionEvent(function, args, kw))
def call_later(interval, function, *args, **kw):
QTimer.singleShot(int(interval*1000), lambda: function(*args, **kw))
@decorator
def run_in_gui_thread(function=None, wait=False):
if function is not None:
@preserve_signature(function)
def function_wrapper(*args, **kw):
application = Application.instance
if QThread.currentThread() is Application.gui_thread:
return function(*args, **kw)
else:
if wait:
executor = FunctionExecutor(function)
application.postEvent(application, CallFunctionEvent(executor, args, kw))
return executor.wait()
else:
application.postEvent(application, CallFunctionEvent(function, args, kw))
return function_wrapper
else:
return partial(run_in_gui_thread, wait=wait)
class Application(object):
__attributes__ = {}
@classproperty
def instance(cls):
try:
return cls.__attributes__['instance']
except KeyError:
return cls.__attributes__.setdefault('instance', QApplication.instance())
@classproperty
def gui_thread(cls):
try:
return cls.__attributes__['gui_thread']
except KeyError:
return cls.__attributes__.setdefault('gui_thread', cls.instance.thread())
class FunctionExecutor(object):
......@@ -56,22 +95,3 @@ class FunctionExecutor(object):
return self.result
@decorator
def run_in_gui_thread(function=None, wait=False):
if function is not None:
@preserve_signature(function)
def function_wrapper(*args, **kw):
application = QApplication.instance()
if application.thread() is QThread.currentThread():
return function(*args, **kw)
else:
if wait:
executor = FunctionExecutor(function)
application.postEvent(application, CallFunctionEvent(executor, args, kw))
return executor.wait()
else:
application.postEvent(application, CallFunctionEvent(function, args, kw))
return function_wrapper
else:
return partial(run_in_gui_thread, wait=wait)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment