Skip to content

Commit

Permalink
Allow calling any function on the main thread (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
hugow authored Jul 30, 2021
1 parent 5e50183 commit b86ef45
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
21 changes: 19 additions & 2 deletions src/packages/mxthread/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ This sample can be saved in a "testmxthread.py" file and then run in 3dsMax.


```python
from mxthread import on_main_thread, main_thread_print
from mxthread import on_main_thread, main_thread_print, run_on_main_thread
from pymxs import runtime as rt
from PySide2.QtCore import QThread

Expand Down Expand Up @@ -104,6 +104,11 @@ class Worker(QThread):

# use a lambda instead
on_main_thread(lambda : print("hello from lambda"))()

# call a function on the main thread without decorating it
def some_function(a, b):
print(f"a = {a} b = {b}")
run_on_main_thread(some_function, 1, 2)

main_thread_print(f"we are done, the sample ran correctly!")

Expand Down Expand Up @@ -136,10 +141,11 @@ we are done, the sample ran correctly!

## How to use mxthread


To create a function that will be executed on the main thread (no matter what thread calls the function),
the function needs to be decorated with `@on_main_thread`, as shown here:

```
```python
@on_main_thread
def do_faulty_stuff():
# we are on main thread so we can use print and it will work
Expand All @@ -151,6 +157,17 @@ def do_faulty_stuff():
Decorated functions can return values and throw exceptions and in both cases this
behaves normally from the thread that calls the function.

### Not using decorators

Alternately, you can simply call a function on the main threads:

```python
def some_function(a, b):
print(f"a = {a} b = {b}")

run_on_main_thread(some_function, 1, 2)
```

### gotcha

The most important gotcha is that the main thread cannot wait for its worker (this
Expand Down
8 changes: 4 additions & 4 deletions src/packages/mxthread/mxthread/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ def run(self, ttd):
RUNNABLE_PAYLOAD_SIGNAL = RunnableWaitablePayloadSignal()
RUNNABLE_PAYLOAD_SIGNAL.sig.connect(RUNNABLE_PAYLOAD_SLOT.run)

def run_on_main_thread(todo):
def run_on_main_thread(todo, *args, **kwargs):
"""
Run code on the main thread.
Returns the return value of the todo code. If this is called
from the main thread, todo is immediately called.
"""
if QThread.currentThread() is QApplication.instance().thread():
return todo()
ttd = RunnableWaitablePayload(todo)
return todo(*args, **kwargs)
ttd = RunnableWaitablePayload(lambda: todo(*args, **kwargs))
return ttd.wait_for_todo_function_to_complete_on_main_thread()

def on_main_thread(func):
Expand All @@ -116,7 +116,7 @@ def on_main_thread(func):
# preserve docstring of the wrapped function
@functools.wraps(func)
def decorated(*args, **kwargs):
return run_on_main_thread(lambda: func(*args, **kwargs))
return run_on_main_thread(func, *args, **kwargs)
return decorated

@on_main_thread
Expand Down

0 comments on commit b86ef45

Please sign in to comment.