From c6233fa47f5a82b0e33864617f12c0f8e732dfc7 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Mon, 5 Jan 2026 22:24:36 -0500 Subject: [PATCH] Expand TileLayer and ColorLayer __init__ documentation; closes #190 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/GridLayers.h | 74 ++++++++++++++++------- tests/issue_190_layer_docs_test.py | 95 ++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 20 deletions(-) create mode 100644 tests/issue_190_layer_docs_test.py diff --git a/src/GridLayers.h b/src/GridLayers.h index 02a5e43..290162d 100644 --- a/src/GridLayers.h +++ b/src/GridLayers.h @@ -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, diff --git a/tests/issue_190_layer_docs_test.py b/tests/issue_190_layer_docs_test.py new file mode 100644 index 0000000..81e4d9e --- /dev/null +++ b/tests/issue_190_layer_docs_test.py @@ -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)