mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
implemented callback warpper for execution in main thread
This commit is contained in:
parent
f511538b49
commit
2944531434
3 changed files with 87 additions and 12 deletions
|
|
@ -22,6 +22,7 @@ from openpype.settings import (
|
||||||
ProjectSettings,
|
ProjectSettings,
|
||||||
DefaultsNotDefined
|
DefaultsNotDefined
|
||||||
)
|
)
|
||||||
|
from openpype.tools.utils import WrappedCallbackItem
|
||||||
|
|
||||||
from .pype_info_widget import PypeInfoWidget
|
from .pype_info_widget import PypeInfoWidget
|
||||||
|
|
||||||
|
|
@ -61,21 +62,24 @@ class TrayManager:
|
||||||
if callback:
|
if callback:
|
||||||
self.execute_in_main_thread(callback)
|
self.execute_in_main_thread(callback)
|
||||||
|
|
||||||
def execute_in_main_thread(self, callback):
|
def execute_in_main_thread(self, callback, *args, **kwargs):
|
||||||
self._main_thread_callbacks.append(callback)
|
if isinstance(callback, WrappedCallbackItem):
|
||||||
|
item = callback
|
||||||
|
else:
|
||||||
|
item = WrappedCallbackItem(callback, *args, **kwargs)
|
||||||
|
|
||||||
|
self._main_thread_callbacks.append(item)
|
||||||
|
|
||||||
|
return item
|
||||||
|
|
||||||
def _main_thread_execution(self):
|
def _main_thread_execution(self):
|
||||||
if self._execution_in_progress:
|
if self._execution_in_progress:
|
||||||
return
|
return
|
||||||
self._execution_in_progress = True
|
self._execution_in_progress = True
|
||||||
while self._main_thread_callbacks:
|
for _ in range(len(self._main_thread_callbacks)):
|
||||||
try:
|
if self._main_thread_callbacks:
|
||||||
callback = self._main_thread_callbacks.popleft()
|
item = self._main_thread_callbacks.popleft()
|
||||||
callback()
|
item.execute()
|
||||||
except:
|
|
||||||
self.log.warning(
|
|
||||||
"Failed to execute {} in main thread".format(callback),
|
|
||||||
exc_info=True)
|
|
||||||
|
|
||||||
self._execution_in_progress = False
|
self._execution_in_progress = False
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ from .widgets import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from .error_dialog import ErrorMessageBox
|
from .error_dialog import ErrorMessageBox
|
||||||
|
from .lib import WrappedCallbackItem
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
|
|
@ -14,5 +15,7 @@ __all__ = (
|
||||||
"ClickableFrame",
|
"ClickableFrame",
|
||||||
"ExpandBtn",
|
"ExpandBtn",
|
||||||
|
|
||||||
"ErrorMessageBox"
|
"ErrorMessageBox",
|
||||||
|
|
||||||
|
"WrappedCallbackItem",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,10 @@ import avalon.api
|
||||||
from avalon import style
|
from avalon import style
|
||||||
from avalon.vendor import qtawesome
|
from avalon.vendor import qtawesome
|
||||||
|
|
||||||
from openpype.api import get_project_settings
|
from openpype.api import (
|
||||||
|
get_project_settings,
|
||||||
|
Logger
|
||||||
|
)
|
||||||
from openpype.lib import filter_profiles
|
from openpype.lib import filter_profiles
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -598,3 +601,68 @@ def is_remove_site_loader(loader):
|
||||||
|
|
||||||
def is_add_site_loader(loader):
|
def is_add_site_loader(loader):
|
||||||
return hasattr(loader, "add_site_to_representation")
|
return hasattr(loader, "add_site_to_representation")
|
||||||
|
|
||||||
|
|
||||||
|
class WrappedCallbackItem:
|
||||||
|
"""Structure to store information about callback and args/kwargs for it.
|
||||||
|
|
||||||
|
Item can be used to execute callback in main thread which may be needed
|
||||||
|
for execution of Qt objects.
|
||||||
|
|
||||||
|
Item store callback (callable variable), arguments and keyword arguments
|
||||||
|
for the callback. Item hold information about it's process.
|
||||||
|
"""
|
||||||
|
not_set = object()
|
||||||
|
_log = None
|
||||||
|
|
||||||
|
def __init__(self, callback, *args, **kwargs):
|
||||||
|
self._done = False
|
||||||
|
self._exception = self.not_set
|
||||||
|
self._result = self.not_set
|
||||||
|
self._callback = callback
|
||||||
|
self._args = args
|
||||||
|
self._kwargs = kwargs
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
self.execute()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def log(self):
|
||||||
|
cls = self.__class__
|
||||||
|
if cls._log is None:
|
||||||
|
cls._log = Logger.get_logger(cls.__name__)
|
||||||
|
return cls._log
|
||||||
|
|
||||||
|
@property
|
||||||
|
def done(self):
|
||||||
|
return self._done
|
||||||
|
|
||||||
|
@property
|
||||||
|
def exception(self):
|
||||||
|
return self._exception
|
||||||
|
|
||||||
|
@property
|
||||||
|
def result(self):
|
||||||
|
return self._result
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
"""Execute callback and store it's result.
|
||||||
|
|
||||||
|
Method must be called from main thread. Item is marked as `done`
|
||||||
|
when callback execution finished. Store output of callback of exception
|
||||||
|
information when callback raise one.
|
||||||
|
"""
|
||||||
|
if self.done:
|
||||||
|
self.log.warning("- item is already processed")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.log.debug("Running callback: {}".format(str(self._callback)))
|
||||||
|
try:
|
||||||
|
result = self._callback(*self._args, **self._kwargs)
|
||||||
|
self._result = result
|
||||||
|
|
||||||
|
except Exception as exc:
|
||||||
|
self._exception = exc
|
||||||
|
|
||||||
|
finally:
|
||||||
|
self._done = True
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue