feat: auto-exit in --headless --exec mode when script completes

Closes #127

Previously, `./mcrogueface --headless --exec <script>` would hang
indefinitely after the script completed because the game loop ran
continuously. This required external timeouts and explicit mcrfpy.exit()
calls in every automation script.

This commit adds automatic exit detection for headless+exec mode:
- Added `auto_exit_after_exec` flag to McRogueFaceConfig
- Set flag automatically when both --headless and --exec are present
- Game loop exits when no timers remain (timers.empty())

Benefits:
- Documentation generation scripts work without explicit exit calls
- Testing scripts don't need timeout wrappers
- Clean process termination for automation
- Backward compatible (scripts with mcrfpy.exit() continue working)

Changes:
- src/McRogueFaceConfig.h: Add auto_exit_after_exec flag
- src/main.cpp: Set flag and recreate engine with modified config
- src/GameEngine.cpp: Check timers.empty() in game loop
- ROADMAP.md: Mark Phase 7 as complete (2025-10-30)
- CLAUDE.md: Add instruction about closing issues with commit messages

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
John McCardle 2025-10-30 22:52:52 -04:00
commit 8f8b72da4a
5 changed files with 21 additions and 3 deletions

View file

@ -284,6 +284,11 @@ void GameEngine::run()
if (!headless && window && !window->isOpen()) {
running = false;
}
// In headless exec mode, auto-exit when no timers remain
if (config.auto_exit_after_exec && timers.empty()) {
running = false;
}
}
// Clean up before exiting the run loop

View file

@ -28,6 +28,9 @@ struct McRogueFaceConfig {
// Screenshot functionality for headless mode
std::string screenshot_path;
bool take_screenshot = false;
// Auto-exit when no timers remain (for --headless --exec automation)
bool auto_exit_after_exec = false;
};
#endif // MCROGUEFACE_CONFIG_H

View file

@ -196,6 +196,14 @@ int run_python_interpreter(const McRogueFaceConfig& config, int argc, char* argv
}
else if (!config.exec_scripts.empty()) {
// With --exec, run the game engine after scripts execute
// In headless mode, auto-exit when no timers remain
McRogueFaceConfig mutable_config = config;
if (mutable_config.headless) {
mutable_config.auto_exit_after_exec = true;
}
delete engine;
engine = new GameEngine(mutable_config);
McRFPy_API::game = engine;
engine->run();
McRFPy_API::api_shutdown();
delete engine;