Regenerate API docs; add threading note to reference intro

Add a one-line threading-contract note to the API reference intro (HTML +
Markdown generators) and regenerate all documentation artifacts (HTML,
Markdown, man page, type stubs) to pick up the updated mcrfpy.lock() docstring.

Refs #327

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
John McCardle 2026-07-02 20:23:28 -04:00
commit c6b21b9a6b
5 changed files with 82 additions and 41 deletions

View file

@ -1,9 +1,11 @@
# McRogueFace API Reference
*Generated on 2026-06-21 12:15:59*
*Generated on 2026-07-02 20:21:29*
*This documentation was dynamically generated from the compiled module.*
**Threading:** any access to mcrfpy objects from a non-main thread must happen inside `with mcrfpy.lock():`; behavior outside the lock is undefined. See [docs/threading-model.md](threading-model.md).
## Table of Contents
- [Functions](#functions)
@ -134,11 +136,11 @@ Get current performance metrics.
### `lock() -> _LockContext`
Get a context manager for thread-safe UI updates from background threads.
Get a context manager for thread-safe access to mcrfpy objects from background threads.
Note:
**Returns:** _LockContext: A context manager that blocks until safe to modify UI Use with `with mcrfpy.lock():` to safely modify UI objects from a background thread. The context manager blocks until the render loop reaches a safe point between frames. Without this, modifying UI from threads may cause visual glitches or crashes.
**Returns:** _LockContext: A context manager that blocks until safe to touch engine objects Any access to mcrfpy objects from a non-main thread must happen inside `with mcrfpy.lock():`; behavior outside the lock is undefined. On a worker thread the context manager blocks (GIL released) until the render loop opens a safe window between frames; on the main thread it is a no-op. See also: Threading Model (docs/threading-model.md)
### `log_benchmark(message: str) -> None`
@ -1092,21 +1094,23 @@ Args:
a: Alpha component (0-255, default 255 = opaque)
Note:
When accessing colors from UI elements (e.g., frame.fill_color),
you receive a COPY of the color. Modifying it doesn't affect the
original. To change a component:
Color is a VALUE TYPE (frozen 1.0 contract): properties that return a
Color (e.g. frame.fill_color) return a fresh COPY, so mutating a component
of the returned object is a silent no-op on the original. The two supported
idioms are read-modify-writeback and whole-value assignment:
# This does NOT work:
frame.fill_color.r = 255 # Modifies a temporary copy
# Do this instead:
# Read-modify-writeback:
c = frame.fill_color
c.r = 255
frame.fill_color = c
# Or use Animation for sub-properties:
anim = mcrfpy.Animation('fill_color.r', 255, 0.5, 'linear')
anim.start(frame)
# Whole-value assignment:
frame.fill_color = mcrfpy.Color(255, 0, 0)
See also: API stability policy (docs/api-stability.md)
**Properties:**
@ -5075,6 +5079,14 @@ Properties:
y (float): Y component.
int (tuple[int, int], read-only): Integer floor of (x, y).
Note:
Vector is a VALUE TYPE (frozen 1.0 contract): properties that return a
Vector return a fresh COPY, so mutating a component of the returned object
is a silent no-op on the original. Use read-modify-writeback
(v = obj.pos; v.x = 5; obj.pos = v) or whole-value assignment
(obj.pos = mcrfpy.Vector(5, 0)).
See also: API stability policy (docs/api-stability.md)
**Properties:**
- `int` *(read-only)*: Integer tuple (floor of x and y) for use as dict keys. Read-only.

View file

@ -108,9 +108,10 @@
<body>
<div class="container">
<h1>McRogueFace API Reference</h1>
<p><em>Generated on 2026-06-21 12:15:59</em></p>
<p><em>Generated on 2026-07-02 20:21:29</em></p>
<p><em>This documentation was dynamically generated from the compiled module.</em></p>
<p><strong>Threading:</strong> any access to mcrfpy objects from a non-main thread must happen inside <code>with mcrfpy.lock():</code>; behavior outside the lock is undefined. See <a href="threading-model.md">docs/threading-model.md</a>.</p>
<div class="toc">
<h2>Table of Contents</h2>
<ul>
@ -249,10 +250,10 @@ Note:</p>
<div class="method-section">
<h3><code class="function-signature">lock() -> _LockContext</code></h3>
<p>Get a context manager for thread-safe UI updates from background threads.
<p>Get a context manager for thread-safe access to mcrfpy objects from background threads.
Note:</p>
<p><span class='returns'>Returns:</span> _LockContext: A context manager that blocks until safe to modify UI Use with `with mcrfpy.lock():` to safely modify UI objects from a background thread. The context manager blocks until the render loop reaches a safe point between frames. Without this, modifying UI from threads may cause visual glitches or crashes.</p>
<p><span class='returns'>Returns:</span> _LockContext: A context manager that blocks until safe to touch engine objects Any access to mcrfpy objects from a non-main thread must happen inside `with mcrfpy.lock():`; behavior outside the lock is undefined. On a worker thread the context manager blocks (GIL released) until the render loop opens a safe window between frames; on the main thread it is a no-op. See also: Threading Model (docs/threading-model.md)</p>
</div>
<div class="method-section">
@ -1232,21 +1233,23 @@ Args:
a: Alpha component (0-255, default 255 = opaque)
Note:
When accessing colors from UI elements (e.g., frame.fill_color),
you receive a COPY of the color. Modifying it doesn&#x27;t affect the
original. To change a component:
Color is a VALUE TYPE (frozen 1.0 contract): properties that return a
Color (e.g. frame.fill_color) return a fresh COPY, so mutating a component
of the returned object is a silent no-op on the original. The two supported
idioms are read-modify-writeback and whole-value assignment:
# This does NOT work:
frame.fill_color.r = 255 # Modifies a temporary copy
# Do this instead:
# Read-modify-writeback:
c = frame.fill_color
c.r = 255
frame.fill_color = c
# Or use Animation for sub-properties:
anim = mcrfpy.Animation(&#x27;fill_color.r&#x27;, 255, 0.5, &#x27;linear&#x27;)
anim.start(frame)
# Whole-value assignment:
frame.fill_color = mcrfpy.Color(255, 0, 0)
See also: API stability policy (docs/api-stability.md)
</p>
<h4>Properties:</h4>
<ul>
@ -5351,6 +5354,14 @@ Properties:
x (float): X component.
y (float): Y component.
int (tuple[int, int], read-only): Integer floor of (x, y).
Note:
Vector is a VALUE TYPE (frozen 1.0 contract): properties that return a
Vector return a fresh COPY, so mutating a component of the returned object
is a silent no-op on the original. Use read-modify-writeback
(v = obj.pos; v.x = 5; obj.pos = v) or whole-value assignment
(obj.pos = mcrfpy.Vector(5, 0)).
See also: API stability policy (docs/api-stability.md)
</p>
<h4>Properties:</h4>
<ul>

View file

@ -14,14 +14,19 @@
. ftr VB CB
. ftr VBI CBI
.\}
.TH "MCRFPY" "3" "2026-06-21" "McRogueFace 0.2.7-prerelease-7drl2026-112-g5eecb2b" ""
.TH "MCRFPY" "3" "2026-07-02" "McRogueFace 0.2.8-6-g19d80b4" ""
.hy
.SH McRogueFace API Reference
.PP
\f[I]Generated on 2026-06-21 12:15:59\f[R]
\f[I]Generated on 2026-07-02 20:21:29\f[R]
.PP
\f[I]This documentation was dynamically generated from the compiled
module.\f[R]
.PP
\f[B]Threading:\f[R] any access to mcrfpy objects from a non-main thread
must happen inside \f[V]with mcrfpy.lock():\f[R]; behavior outside the
lock is undefined.
See docs/threading-model.md.
.SS Table of Contents
.IP \[bu] 2
Functions
@ -223,18 +228,19 @@ rendered this frame), total_entities (total entity count across all
grids)
.SS \f[V]lock() -> _LockContext\f[R]
.PP
Get a context manager for thread-safe UI updates from background
threads.
Get a context manager for thread-safe access to mcrfpy objects from
background threads.
.PP
Note:
.PP
\f[B]Returns:\f[R] _LockContext: A context manager that blocks until
safe to modify UI Use with \f[V]with mcrfpy.lock():\f[R] to safely
modify UI objects from a background thread.
The context manager blocks until the render loop reaches a safe point
between frames.
Without this, modifying UI from threads may cause visual glitches or
crashes.
safe to touch engine objects Any access to mcrfpy objects from a
non-main thread must happen inside \f[V]with mcrfpy.lock():\f[R];
behavior outside the lock is undefined.
On a worker thread the context manager blocks (GIL released) until the
render loop opens a safe window between frames; on the main thread it is
a no-op.
See also: Threading Model (docs/threading-model.md)
.SS \f[V]log_benchmark(message: str) -> None\f[R]
.PP
Add a log message to the current benchmark frame.
@ -1280,24 +1286,26 @@ RGBA color representation.
Args: r: Red component (0-255) g: Green component (0-255) b: Blue
component (0-255) a: Alpha component (0-255, default 255 = opaque)
.PP
Note: When accessing colors from UI elements (e.g., frame.fill_color),
you receive a COPY of the color.
Modifying it doesn\[cq]t affect the original.
To change a component:
Note: Color is a VALUE TYPE (frozen 1.0 contract): properties that
return a Color (e.g.\ frame.fill_color) return a fresh COPY, so mutating
a component of the returned object is a silent no-op on the original.
The two supported idioms are read-modify-writeback and whole-value
assignment:
.IP
.nf
\f[C]
# This does NOT work:
frame.fill_color.r = 255 # Modifies a temporary copy
# Do this instead:
# Read-modify-writeback:
c = frame.fill_color
c.r = 255
frame.fill_color = c
# Or use Animation for sub-properties:
anim = mcrfpy.Animation(\[aq]fill_color.r\[aq], 255, 0.5, \[aq]linear\[aq])
anim.start(frame)
# Whole-value assignment:
frame.fill_color = mcrfpy.Color(255, 0, 0)
See also: API stability policy (docs/api-stability.md)
\f[R]
.fi
.PP
@ -5380,6 +5388,13 @@ Properties: x (float): X component.
y (float): Y component.
int (tuple[int, int], read-only): Integer floor of (x, y).
.PP
Note: Vector is a VALUE TYPE (frozen 1.0 contract): properties that
return a Vector return a fresh COPY, so mutating a component of the
returned object is a silent no-op on the original.
Use read-modify-writeback (v = obj.pos; v.x = 5; obj.pos = v) or
whole-value assignment (obj.pos = mcrfpy.Vector(5, 0)).
See also: API stability policy (docs/api-stability.md)
.PP
\f[B]Properties:\f[R] - \f[V]int\f[R] \f[I](read-only)\f[R]: Integer
tuple (floor of x and y) for use as dict keys.
Read-only.

View file

@ -2034,7 +2034,7 @@ def get_metrics() -> dict:
"""Get current performance metrics."""
...
def lock() -> _LockContext:
"""Get a context manager for thread-safe UI updates from background threads."""
"""Get a context manager for thread-safe access to mcrfpy objects from background threads."""
...
def log_benchmark(message: str) -> None:
"""Add a log message to the current benchmark frame."""

View file

@ -369,7 +369,8 @@ def generate_html_docs():
<h1>McRogueFace API Reference</h1>
<p><em>Generated on {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</em></p>
<p><em>This documentation was dynamically generated from the compiled module.</em></p>
<p><strong>Threading:</strong> any access to mcrfpy objects from a non-main thread must happen inside <code>with mcrfpy.lock():</code>; behavior outside the lock is undefined. See <a href="threading-model.md">docs/threading-model.md</a>.</p>
<div class="toc">
<h2>Table of Contents</h2>
<ul>
@ -517,6 +518,8 @@ def generate_markdown_docs():
*This documentation was dynamically generated from the compiled module.*
**Threading:** any access to mcrfpy objects from a non-main thread must happen inside `with mcrfpy.lock():`; behavior outside the lock is undefined. See [docs/threading-model.md](threading-model.md).
## Table of Contents
- [Functions](#functions)