Commits

Henning Schröder committed ffc6b95

added async calls for more responsive ui

Comments (0)

Files changed (3)

 import inspect
 from zipimport import zipimporter
 
-
 import rope.base.libutils
 import rope.contrib.codeassist
 
+from pycode.utils import async
 
-        
+
+
 def completions(project, source_code, offset, filename="XXXunknownXXX.py"):
 	# TODO:
 	#  * include import completitions
     try:
         proposals = rope.contrib.codeassist.code_assist(project._rope_prj, source_code, offset, resource)
         proposals = rope.contrib.codeassist.sorted_proposals(proposals)
-        return [(proposal.type, proposal.name) for proposal in proposals]
+        result = [(proposal.type, proposal.name) for proposal in proposals]
     except Exception, _error:
         print _error
-        return []
+        result = []
+    return result
+
+
+async_completions = async(completions)
 
     
 def calltip(project, source_code, offset, filename="XXXunknownXXX.py"):
     return ("", "")
 
 
+async_calltip = async(calltip)
+
 
 def definition_location(project, source_code, offset, filename="XXXunknownXXX.py"):
     try:
 
 
 
+async_definition_location = async(definition_location)
+
+
+
+
 db = {}
 
 

pycode/qtintegration.py

 # -*- coding: utf-8 -*-
 from collections import namedtuple
 
-from PyQt4.QtCore import SIGNAL, QAbstractListModel, Qt, QVariant, QModelIndex, QAbstractTableModel, pyqtSignal
+from PyQt4.QtCore import SIGNAL, QAbstractListModel, Qt, QVariant, QModelIndex, QAbstractTableModel, pyqtSignal, QThread
 from PyQt4.QtGui import (
     QToolTip, QTreeWidget, QTreeWidgetItem, QTextCursor, QFrame, QIcon, QCompleter, QTableView, QAbstractItemView, QKeyEvent)
 
-from pycode.assist import completions, calltip, definition_location
+from pycode.assist import async_completions, async_calltip, async_definition_location
 from pycode.indenter import PythonCodeIndenter
 
+from pycode.utils import set_async_method
+
+
+
+class AsyncQThread(QThread):
+
+    
+    def __init__(self, target, args, kwargs):
+        super(AsyncQThread, self).__init__()
+        self.target = target
+        self.args = args
+        self.callback = kwargs.pop("callback")
+        self.kwargs = kwargs
+        self.finished.connect(self.on_finished)
+        
+
+    def run(self):
+        self.result = self.target(*self.args, **self.kwargs)
+
+
+    def on_finished(self):
+        # slot called in main (gui) thread
+        self.callback(self.result)
+        self.args = self.kwargs = self.target = None
+
+
+        
+def async_pyqt(func, *args, **kwargs):
+    func._thread = AsyncQThread(func, args=args, kwargs=kwargs)
+    func._thread.start()
+
+
+set_async_method(async_pyqt)
+
 
 
 class LineEditor(object):
         
     def isVisible(self):
         return QToolTip.isVisible()
-    
+
+
     
     
 class PyCode(object):
         pos = self._textedit.textCursor().position()
         return src, pos
 
-        
+
+    
     def request_completion(self):
         src, pos = self.source()
-        clist = [Completion(c[0], c[1]) for c in completions(self._prj, src, pos)]
+        async_completions(self._prj, src, pos, callback=self.got_completions)
+
+
+    def got_completions(self, result):
+        clist = [Completion(c[0], c[1]) for c in result]
         self._completer.on_completitions_found(clist)
-        
+
         
     def request_definition(self):
         src, pos = self.source()
-        print "defined at", definition_location(self._prj, src, pos)
+        async_definition_location(self._prj, src, pos, callback=self.got_definition)
 
+        
+    def got_definition(self, result):
+        print "defined at", result
+        
 
     def request_calltip(self):
         src, pos = self.source()
-        signature, doc = calltip(self._prj, src, pos-1)
+        async_calltip(self._prj, src, pos-1, callback=self.got_calltip)
+
+        
+    def got_calltip(self, result):
+        (signature, doc) = result
         if signature:
             self._calltip.show(signature, doc)
 
+# -*- coding: utf-8 -*-
+from threading import Thread
+
+_async_method = None
+
+
+def set_async_method(handler):
+    global _async_method
+    _async_method = handler
+
+
+
+def sync_call(func, *args, **kwargs):
+    callback = kwargs.pop("callback")
+    result = func(*args, **kwargs)
+    callback(result)
+
+
+
+class _AsyncThread(Thread):
+
+        
+    def run(self):
+        kwargs = self.kwargs
+        callback = kwargs.pop("callback")
+        func = self.args[0]
+        args = self.args[1:]
+        result = func(*args, **kwargs)
+        callback(result)
+
+
+        
+def threaded_call(func, *args, **kwargs):
+    t = _AsyncThread(args=(func,)+args, kwargs=kwargs)
+    t.start()
+
+    
+def async(func):
+    def wrapper(*args, **kwargs):
+        _async_method(func, *args, **kwargs)
+    return wrapper
+