diff --git a/src/McRFPy_API.cpp b/src/McRFPy_API.cpp index 1e8c212..f759b0a 100644 --- a/src/McRFPy_API.cpp +++ b/src/McRFPy_API.cpp @@ -24,30 +24,161 @@ PyObject* McRFPy_API::mcrf_module; static PyMethodDef mcrfpyMethods[] = { - {"createSoundBuffer", McRFPy_API::_createSoundBuffer, METH_VARARGS, "(filename)"}, - {"loadMusic", McRFPy_API::_loadMusic, METH_VARARGS, "(filename)"}, - {"setMusicVolume", McRFPy_API::_setMusicVolume, METH_VARARGS, "(int)"}, - {"setSoundVolume", McRFPy_API::_setSoundVolume, METH_VARARGS, "(int)"}, - {"playSound", McRFPy_API::_playSound, METH_VARARGS, "(int)"}, - {"getMusicVolume", McRFPy_API::_getMusicVolume, METH_VARARGS, ""}, - {"getSoundVolume", McRFPy_API::_getSoundVolume, METH_VARARGS, ""}, + {"createSoundBuffer", McRFPy_API::_createSoundBuffer, METH_VARARGS, + "createSoundBuffer(filename: str) -> int\n\n" + "Load a sound effect from a file and return its buffer ID.\n\n" + "Args:\n" + " filename: Path to the sound file (WAV, OGG, FLAC)\n\n" + "Returns:\n" + " int: Buffer ID for use with playSound()\n\n" + "Raises:\n" + " RuntimeError: If the file cannot be loaded"}, + {"loadMusic", McRFPy_API::_loadMusic, METH_VARARGS, + "loadMusic(filename: str) -> None\n\n" + "Load and immediately play background music from a file.\n\n" + "Args:\n" + " filename: Path to the music file (WAV, OGG, FLAC)\n\n" + "Note:\n" + " Only one music track can play at a time. Loading new music stops the current track."}, + {"setMusicVolume", McRFPy_API::_setMusicVolume, METH_VARARGS, + "setMusicVolume(volume: int) -> None\n\n" + "Set the global music volume.\n\n" + "Args:\n" + " volume: Volume level from 0 (silent) to 100 (full volume)"}, + {"setSoundVolume", McRFPy_API::_setSoundVolume, METH_VARARGS, + "setSoundVolume(volume: int) -> None\n\n" + "Set the global sound effects volume.\n\n" + "Args:\n" + " volume: Volume level from 0 (silent) to 100 (full volume)"}, + {"playSound", McRFPy_API::_playSound, METH_VARARGS, + "playSound(buffer_id: int) -> None\n\n" + "Play a sound effect using a previously loaded buffer.\n\n" + "Args:\n" + " buffer_id: Sound buffer ID returned by createSoundBuffer()\n\n" + "Raises:\n" + " RuntimeError: If the buffer ID is invalid"}, + {"getMusicVolume", McRFPy_API::_getMusicVolume, METH_NOARGS, + "getMusicVolume() -> int\n\n" + "Get the current music volume level.\n\n" + "Returns:\n" + " int: Current volume (0-100)"}, + {"getSoundVolume", McRFPy_API::_getSoundVolume, METH_NOARGS, + "getSoundVolume() -> int\n\n" + "Get the current sound effects volume level.\n\n" + "Returns:\n" + " int: Current volume (0-100)"}, - {"sceneUI", McRFPy_API::_sceneUI, METH_VARARGS, "sceneUI(scene) - Returns a list of UI elements"}, + {"sceneUI", McRFPy_API::_sceneUI, METH_VARARGS, + "sceneUI(scene: str = None) -> list\n\n" + "Get all UI elements for a scene.\n\n" + "Args:\n" + " scene: Scene name. If None, uses current scene\n\n" + "Returns:\n" + " list: All UI elements (Frame, Caption, Sprite, Grid) in the scene\n\n" + "Raises:\n" + " KeyError: If the specified scene doesn't exist"}, - {"currentScene", McRFPy_API::_currentScene, METH_VARARGS, "currentScene() - Current scene's name. Returns a string"}, - {"setScene", McRFPy_API::_setScene, METH_VARARGS, "setScene(scene, transition=None, duration=0.0) - transition to a different scene. Transition can be 'fade', 'slide_left', 'slide_right', 'slide_up', or 'slide_down'"}, - {"createScene", McRFPy_API::_createScene, METH_VARARGS, "createScene(scene) - create a new blank scene with given name"}, - {"keypressScene", McRFPy_API::_keypressScene, METH_VARARGS, "keypressScene(callable) - assign a callable object to the current scene receive keypress events"}, + {"currentScene", McRFPy_API::_currentScene, METH_NOARGS, + "currentScene() -> str\n\n" + "Get the name of the currently active scene.\n\n" + "Returns:\n" + " str: Name of the current scene"}, + {"setScene", McRFPy_API::_setScene, METH_VARARGS, + "setScene(scene: str, transition: str = None, duration: float = 0.0) -> None\n\n" + "Switch to a different scene with optional transition effect.\n\n" + "Args:\n" + " scene: Name of the scene to switch to\n" + " transition: Transition type ('fade', 'slide_left', 'slide_right', 'slide_up', 'slide_down')\n" + " duration: Transition duration in seconds (default: 0.0 for instant)\n\n" + "Raises:\n" + " KeyError: If the scene doesn't exist\n" + " ValueError: If the transition type is invalid"}, + {"createScene", McRFPy_API::_createScene, METH_VARARGS, + "createScene(name: str) -> None\n\n" + "Create a new empty scene.\n\n" + "Args:\n" + " name: Unique name for the new scene\n\n" + "Raises:\n" + " ValueError: If a scene with this name already exists\n\n" + "Note:\n" + " The scene is created but not made active. Use setScene() to switch to it."}, + {"keypressScene", McRFPy_API::_keypressScene, METH_VARARGS, + "keypressScene(handler: callable) -> None\n\n" + "Set the keyboard event handler for the current scene.\n\n" + "Args:\n" + " handler: Callable that receives (key_name: str, is_pressed: bool)\n\n" + "Example:\n" + " def on_key(key, pressed):\n" + " if key == 'A' and pressed:\n" + " print('A key pressed')\n" + " mcrfpy.keypressScene(on_key)"}, - {"setTimer", McRFPy_API::_setTimer, METH_VARARGS, "setTimer(name:str, callable:object, interval:int) - callable will be called with args (runtime:float) every `interval` milliseconds"}, - {"delTimer", McRFPy_API::_delTimer, METH_VARARGS, "delTimer(name:str) - stop calling the timer labelled with `name`"}, - {"exit", McRFPy_API::_exit, METH_VARARGS, "exit() - close down the game engine"}, - {"setScale", McRFPy_API::_setScale, METH_VARARGS, "setScale(multiplier:float) - resize the window (still 1024x768, but bigger)"}, + {"setTimer", McRFPy_API::_setTimer, METH_VARARGS, + "setTimer(name: str, handler: callable, interval: int) -> None\n\n" + "Create or update a recurring timer.\n\n" + "Args:\n" + " name: Unique identifier for the timer\n" + " handler: Function called with (runtime: float) parameter\n" + " interval: Time between calls in milliseconds\n\n" + "Note:\n" + " If a timer with this name exists, it will be replaced.\n" + " The handler receives the total runtime in seconds as its argument."}, + {"delTimer", McRFPy_API::_delTimer, METH_VARARGS, + "delTimer(name: str) -> None\n\n" + "Stop and remove a timer.\n\n" + "Args:\n" + " name: Timer identifier to remove\n\n" + "Note:\n" + " No error is raised if the timer doesn't exist."}, + {"exit", McRFPy_API::_exit, METH_NOARGS, + "exit() -> None\n\n" + "Cleanly shut down the game engine and exit the application.\n\n" + "Note:\n" + " This immediately closes the window and terminates the program."}, + {"setScale", McRFPy_API::_setScale, METH_VARARGS, + "setScale(multiplier: float) -> None\n\n" + "Scale the game window size.\n\n" + "Args:\n" + " multiplier: Scale factor (e.g., 2.0 for double size)\n\n" + "Note:\n" + " The internal resolution remains 1024x768, but the window is scaled.\n" + " This is deprecated - use Window.resolution instead."}, - {"find", McRFPy_API::_find, METH_VARARGS, "find(name, scene=None) - find first UI element with given name"}, - {"findAll", McRFPy_API::_findAll, METH_VARARGS, "findAll(pattern, scene=None) - find all UI elements matching name pattern (supports * wildcards)"}, + {"find", McRFPy_API::_find, METH_VARARGS, + "find(name: str, scene: str = None) -> UIDrawable | None\n\n" + "Find the first UI element with the specified name.\n\n" + "Args:\n" + " name: Exact name to search for\n" + " scene: Scene to search in (default: current scene)\n\n" + "Returns:\n" + " Frame, Caption, Sprite, Grid, or Entity if found; None otherwise\n\n" + "Note:\n" + " Searches scene UI elements and entities within grids."}, + {"findAll", McRFPy_API::_findAll, METH_VARARGS, + "findAll(pattern: str, scene: str = None) -> list\n\n" + "Find all UI elements matching a name pattern.\n\n" + "Args:\n" + " pattern: Name pattern with optional wildcards (* matches any characters)\n" + " scene: Scene to search in (default: current scene)\n\n" + "Returns:\n" + " list: All matching UI elements and entities\n\n" + "Example:\n" + " findAll('enemy*') # Find all elements starting with 'enemy'\n" + " findAll('*_button') # Find all elements ending with '_button'"}, - {"getMetrics", McRFPy_API::_getMetrics, METH_VARARGS, "getMetrics() - get performance metrics (returns dict)"}, + {"getMetrics", McRFPy_API::_getMetrics, METH_NOARGS, + "getMetrics() -> dict\n\n" + "Get current performance metrics.\n\n" + "Returns:\n" + " dict: Performance data with keys:\n" + " - frame_time: Last frame duration in seconds\n" + " - avg_frame_time: Average frame time\n" + " - fps: Frames per second\n" + " - draw_calls: Number of draw calls\n" + " - ui_elements: Total UI element count\n" + " - visible_elements: Visible element count\n" + " - current_frame: Frame counter\n" + " - runtime: Total runtime in seconds"}, {NULL, NULL, 0, NULL} }; @@ -55,7 +186,27 @@ static PyMethodDef mcrfpyMethods[] = { static PyModuleDef mcrfpyModule = { PyModuleDef_HEAD_INIT, /* m_base - Always initialize this member to PyModuleDef_HEAD_INIT. */ "mcrfpy", /* m_name */ - NULL, /* m_doc - Docstring for the module; usually a docstring variable created with PyDoc_STRVAR is used. */ + PyDoc_STR("McRogueFace Python API\\n\\n" + "Core game engine interface for creating roguelike games with Python.\\n\\n" + "This module provides:\\n" + "- Scene management (createScene, setScene, currentScene)\\n" + "- UI components (Frame, Caption, Sprite, Grid)\\n" + "- Entity system for game objects\\n" + "- Audio playback (sound effects and music)\\n" + "- Timer system for scheduled events\\n" + "- Input handling\\n" + "- Performance metrics\\n\\n" + "Example:\\n" + " import mcrfpy\\n" + " \\n" + " # Create a new scene\\n" + " mcrfpy.createScene('game')\\n" + " mcrfpy.setScene('game')\\n" + " \\n" + " # Add UI elements\\n" + " frame = mcrfpy.Frame(10, 10, 200, 100)\\n" + " caption = mcrfpy.Caption('Hello World', 50, 50)\\n" + " mcrfpy.sceneUI().extend([frame, caption])\\n"), -1, /* m_size - Setting m_size to -1 means that the module does not support sub-interpreters, because it has global state. */ mcrfpyMethods, /* m_methods */ NULL, /* m_slots - An array of slot definitions ... When using single-phase initialization, m_slots must be NULL. */