Enables background Python threads to safely modify UI objects by
synchronizing with the render loop at frame boundaries.
Implementation:
- FrameLock class provides mutex/condvar synchronization
- GIL released during window.display() allowing background threads to run
- Safe window opens between frames for synchronized UI updates
- mcrfpy.lock() context manager blocks until safe window, then executes
- Main thread detection: lock() is a no-op when called from callbacks
or script initialization (already synchronized)
Usage:
import threading
import mcrfpy
def background_worker():
with mcrfpy.lock(): # Blocks until safe
player.x = new_x # Safe to modify UI
threading.Thread(target=background_worker).start()
The lock works transparently from any context - background threads get
actual synchronization, main thread calls (callbacks, init) get no-op.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
25 lines
683 B
C++
25 lines
683 B
C++
#pragma once
|
|
// #219 - Thread synchronization context manager for mcrfpy.lock()
|
|
|
|
#include <Python.h>
|
|
|
|
// Forward declaration
|
|
class GameEngine;
|
|
|
|
// PyLockContext - the context manager object returned by mcrfpy.lock()
|
|
typedef struct {
|
|
PyObject_HEAD
|
|
bool acquired; // Track if we've acquired the lock
|
|
} PyLockContextObject;
|
|
|
|
// The type object for the context manager
|
|
extern PyTypeObject PyLockContextType;
|
|
|
|
// Module initialization function - adds lock() function to module
|
|
namespace PyLock {
|
|
// Create the lock() function that returns a context manager
|
|
PyObject* lock(PyObject* self, PyObject* args);
|
|
|
|
// Initialize the type (call PyType_Ready)
|
|
int init();
|
|
}
|