docs: Fix property extraction and add Scene documentation

Doc generator fixes (tools/generate_dynamic_docs.py):
- Add types.GetSetDescriptorType detection for C++ extension properties
- All 22 classes with properties now have documented Properties sections
- Read-only detection via "read-only" docstring convention

Scene class documentation (src/PySceneObject.h):
- Expanded tp_doc with constructor, properties, lifecycle callbacks
- Documents key advantage: on_key works on ANY scene
- Includes usage examples for basic and subclass patterns

CLAUDE.md additions:
- New section "Adding Documentation for New Python Types"
- Step-by-step guide for tp_doc, PyMethodDef, PyGetSetDef
- Documentation extraction details and troubleshooting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John McCardle 2025-12-29 19:48:21 -05:00
commit e64c5c147f
5 changed files with 835 additions and 5 deletions

View file

@ -53,7 +53,41 @@ namespace mcrfpydef {
.tp_dealloc = (destructor)PySceneClass::__dealloc,
.tp_repr = (reprfunc)PySceneClass::__repr__,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // Allow subclassing
.tp_doc = PyDoc_STR("Base class for object-oriented scenes"),
.tp_doc = PyDoc_STR(
"Scene(name: str)\n\n"
"Object-oriented scene management with lifecycle callbacks.\n\n"
"This is the recommended approach for scene management, replacing module-level\n"
"functions like createScene(), setScene(), and sceneUI(). Key advantage: you can\n"
"set on_key handlers on ANY scene, not just the currently active one.\n\n"
"Args:\n"
" name: Unique identifier for this scene. Used for scene transitions.\n\n"
"Properties:\n"
" name (str, read-only): Scene's unique identifier.\n"
" active (bool, read-only): Whether this scene is currently displayed.\n"
" children (UICollection, read-only): UI elements in this scene. Modify to add/remove elements.\n"
" on_key (callable): Keyboard handler. Set on ANY scene, regardless of which is active!\n"
" pos (Vector): Position offset for all UI elements.\n"
" visible (bool): Whether the scene renders.\n"
" opacity (float): Scene transparency (0.0-1.0).\n\n"
"Lifecycle Callbacks (override in subclass):\n"
" on_enter(): Called when scene becomes active via activate().\n"
" on_exit(): Called when scene is deactivated (another scene activates).\n"
" on_keypress(key: str, action: str): Called for keyboard events. Alternative to on_key property.\n"
" update(dt: float): Called every frame with delta time in seconds.\n"
" on_resize(width: int, height: int): Called when window is resized.\n\n"
"Example:\n"
" # Basic usage (replacing module functions):\n"
" scene = mcrfpy.Scene('main_menu')\n"
" scene.children.append(mcrfpy.Caption(text='Welcome', pos=(100, 100)))\n"
" scene.on_key = lambda key, action: print(f'Key: {key}')\n"
" scene.activate() # Switch to this scene\n\n"
" # Subclassing for lifecycle:\n"
" class GameScene(mcrfpy.Scene):\n"
" def on_enter(self):\n"
" print('Game started!')\n"
" def update(self, dt):\n"
" self.player.move(dt)\n"
),
.tp_methods = nullptr, // Set in McRFPy_API.cpp
.tp_getset = nullptr, // Set in McRFPy_API.cpp
.tp_init = (initproc)PySceneClass::__init__,