Expand TileLayer and ColorLayer __init__ documentation; closes #190

Enhanced tp_doc strings for both layer types to include:
- What happens when grid_size=None (inherits from parent Grid)
- That layers are created via Grid.add_layer() rather than directly
- FOV-related methods for ColorLayer
- Tile index -1 meaning no tile/transparent for TileLayer
- fill_rect method documentation
- Comprehensive usage examples

🤖 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 2026-01-05 22:24:36 -05:00
commit c6233fa47f
2 changed files with 149 additions and 20 deletions

View file

@ -253,18 +253,33 @@ namespace mcrfpydef {
.tp_repr = (reprfunc)PyGridLayerAPI::ColorLayer_repr,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = PyDoc_STR("ColorLayer(z_index=-1, grid_size=None)\n\n"
"A grid layer that stores RGBA colors per cell.\n\n"
"A grid layer that stores RGBA colors per cell for background/overlay effects.\n\n"
"ColorLayers are typically created via Grid.add_layer('color', ...) rather than\n"
"instantiated directly. When attached to a Grid, the layer inherits rendering\n"
"parameters and can participate in FOV (field of view) calculations.\n\n"
"Args:\n"
" z_index (int): Render order. Negative = below entities. Default: -1\n"
" grid_size (tuple): Dimensions as (width, height). Default: parent grid size\n\n"
" z_index (int): Render order relative to entities. Negative values render\n"
" below entities (as backgrounds), positive values render above entities\n"
" (as overlays). Default: -1 (background)\n"
" grid_size (tuple): Dimensions as (width, height). If None, the layer will\n"
" inherit the parent Grid's dimensions when attached. Default: None\n\n"
"Attributes:\n"
" z_index (int): Layer z-order relative to entities\n"
" visible (bool): Whether layer is rendered\n"
" grid_size (tuple): Layer dimensions (read-only)\n\n"
" z_index (int): Layer z-order relative to entities (read/write)\n"
" visible (bool): Whether layer is rendered (read/write)\n"
" grid_size (tuple): Layer dimensions as (width, height) (read-only)\n\n"
"Methods:\n"
" at(x, y): Get color at cell position\n"
" set(x, y, color): Set color at cell position\n"
" fill(color): Fill entire layer with color"),
" at(x, y) -> Color: Get the color at cell position (x, y)\n"
" set(x, y, color): Set the color at cell position (x, y)\n"
" fill(color): Fill the entire layer with a single color\n"
" fill_rect(x, y, w, h, color): Fill a rectangular region with a color\n"
" draw_fov(...): Draw FOV-based visibility colors\n"
" apply_perspective(entity, ...): Bind layer to entity for automatic FOV updates\n\n"
"Example:\n"
" grid = mcrfpy.Grid(grid_size=(20, 15), texture=my_texture,\n"
" pos=(50, 50), size=(640, 480))\n"
" layer = grid.add_layer('color', z_index=-1)\n"
" layer.fill(mcrfpy.Color(40, 40, 40)) # Dark gray background\n"
" layer.set(5, 5, mcrfpy.Color(255, 0, 0, 128)) # Semi-transparent red cell"),
.tp_methods = PyGridLayerAPI::ColorLayer_methods,
.tp_getset = PyGridLayerAPI::ColorLayer_getsetters,
.tp_init = (initproc)PyGridLayerAPI::ColorLayer_init,
@ -289,20 +304,39 @@ namespace mcrfpydef {
.tp_repr = (reprfunc)PyGridLayerAPI::TileLayer_repr,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = PyDoc_STR("TileLayer(z_index=-1, texture=None, grid_size=None)\n\n"
"A grid layer that stores sprite indices per cell.\n\n"
"A grid layer that stores sprite indices per cell for tile-based rendering.\n\n"
"TileLayers are typically created via Grid.add_layer('tile', ...) rather than\n"
"instantiated directly. Each cell stores an integer index into the layer's\n"
"sprite atlas texture. An index of -1 means no tile (transparent/empty).\n\n"
"Args:\n"
" z_index (int): Render order. Negative = below entities. Default: -1\n"
" texture (Texture): Sprite atlas for tile rendering. Default: None\n"
" grid_size (tuple): Dimensions as (width, height). Default: parent grid size\n\n"
" z_index (int): Render order relative to entities. Negative values render\n"
" below entities (as backgrounds), positive values render above entities\n"
" (as overlays). Default: -1 (background)\n"
" texture (Texture): Sprite atlas containing tile images. The texture's\n"
" sprite_size determines individual tile dimensions. Required for\n"
" rendering; can be set after creation. Default: None\n"
" grid_size (tuple): Dimensions as (width, height). If None, the layer will\n"
" inherit the parent Grid's dimensions when attached. Default: None\n\n"
"Attributes:\n"
" z_index (int): Layer z-order relative to entities\n"
" visible (bool): Whether layer is rendered\n"
" texture (Texture): Tile sprite atlas\n"
" grid_size (tuple): Layer dimensions (read-only)\n\n"
" z_index (int): Layer z-order relative to entities (read/write)\n"
" visible (bool): Whether layer is rendered (read/write)\n"
" texture (Texture): Sprite atlas for tile images (read/write)\n"
" grid_size (tuple): Layer dimensions as (width, height) (read-only)\n\n"
"Methods:\n"
" at(x, y): Get tile index at cell position\n"
" set(x, y, index): Set tile index at cell position\n"
" fill(index): Fill entire layer with tile index"),
" at(x, y) -> int: Get the tile index at cell position (x, y)\n"
" set(x, y, index): Set the tile index at cell position (x, y)\n"
" fill(index): Fill the entire layer with a single tile index\n"
" fill_rect(x, y, w, h, index): Fill a rectangular region with a tile index\n\n"
"Tile Index Values:\n"
" -1: No tile (transparent/empty cell)\n"
" 0+: Index into the texture's sprite atlas (row-major order)\n\n"
"Example:\n"
" grid = mcrfpy.Grid(grid_size=(20, 15), texture=my_texture,\n"
" pos=(50, 50), size=(640, 480))\n"
" layer = grid.add_layer('tile', z_index=1, texture=overlay_texture)\n"
" layer.fill(-1) # Clear layer (all transparent)\n"
" layer.set(5, 5, 42) # Place tile index 42 at position (5, 5)\n"
" layer.fill_rect(0, 0, 20, 1, 10) # Top row filled with tile 10"),
.tp_methods = PyGridLayerAPI::TileLayer_methods,
.tp_getset = PyGridLayerAPI::TileLayer_getsetters,
.tp_init = (initproc)PyGridLayerAPI::TileLayer_init,

View file

@ -0,0 +1,95 @@
#!/usr/bin/env python3
"""Test for issue #190: Expanded TileLayer and ColorLayer __init__ documentation.
This test verifies that the documentation for ColorLayer and TileLayer
contains the expected key phrases and is comprehensive.
"""
import mcrfpy
import sys
def test_colorlayer_docs():
"""Test ColorLayer documentation completeness."""
doc = mcrfpy.ColorLayer.__doc__
if not doc:
print("FAIL: ColorLayer.__doc__ is empty or None")
return False
print("=== ColorLayer Documentation ===")
print(doc)
print()
# Check for key phrases
required_phrases = [
"grid_size",
"z_index",
"RGBA",
"at(x, y)",
"set(x, y",
"fill(",
"Grid.add_layer",
"visible",
"Example",
]
missing = []
for phrase in required_phrases:
if phrase not in doc:
missing.append(phrase)
if missing:
print(f"FAIL: ColorLayer docs missing phrases: {missing}")
return False
print("ColorLayer documentation: PASS")
return True
def test_tilelayer_docs():
"""Test TileLayer documentation completeness."""
doc = mcrfpy.TileLayer.__doc__
if not doc:
print("FAIL: TileLayer.__doc__ is empty or None")
return False
print("=== TileLayer Documentation ===")
print(doc)
print()
# Check for key phrases
required_phrases = [
"grid_size",
"z_index",
"texture",
"at(x, y)",
"set(x, y",
"fill(",
"-1", # Special value for no tile
"sprite",
"Grid.add_layer",
"visible",
"Example",
]
missing = []
for phrase in required_phrases:
if phrase not in doc:
missing.append(phrase)
if missing:
print(f"FAIL: TileLayer docs missing phrases: {missing}")
return False
print("TileLayer documentation: PASS")
return True
# Run tests
colorlayer_ok = test_colorlayer_docs()
tilelayer_ok = test_tilelayer_docs()
if colorlayer_ok and tilelayer_ok:
print("\nAll documentation tests PASSED")
sys.exit(0)
else:
print("\nDocumentation tests FAILED")
sys.exit(1)