From 817a0b76f370e9318af4d54b8163b98b2713507d Mon Sep 17 00:00:00 2001 From: LoafyLemon Date: Sun, 19 May 2024 16:37:35 +0100 Subject: [PATCH] Implement Ren'Py Context Passthrough for the console --- game/scripts/utility/console.rpy | 58 ++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/game/scripts/utility/console.rpy b/game/scripts/utility/console.rpy index 49cfeabc..6445812c 100644 --- a/game/scripts/utility/console.rpy +++ b/game/scripts/utility/console.rpy @@ -4,6 +4,25 @@ default persistent.console_line_history = None init 1702 python in _console: import datetime + class ScriptErrorHandlerConsole(object): + """ + Handles error in Ren'Py script. + """ + + def __init__(self): + self.target_depth = renpy.call_stack_depth() + + def __call__(self, short, full, traceback_fn): + he = console.history[-1] + he.result = short.split("\n")[-2] + he.is_error = True + + if renpy.get_return_stack(): + while renpy.call_stack_depth() > self.target_depth: + renpy.pop_call() + + renpy.jump("console") + class ConsoleHistoryEntry(object): lines = 0 @@ -195,11 +214,11 @@ init 1702 python in _console: # Try to run it as Ren'Py. if self.can_renpy(): - # TODO: Can we run Ren'Py code? + # Can we run Ren'Py code? name = renpy.load_string(code + "\nreturn") if name is not None: - renpy.game.context().exception_handler = ScriptErrorHandler() + renpy.game.context().exception_handler = ScriptErrorHandlerConsole() renpy.call(name) else: error = "\n\n".join(renpy.get_parse_errors()) @@ -250,10 +269,12 @@ init 1702 python in _console: @command(_("exit: exit the console")) def exit(l): renpy.hide_screen("console") + renpy.return_statement() @command() def quit(l): renpy.hide_screen("console") + renpy.return_statement() @command() def stack(l): @@ -334,6 +355,14 @@ init 1702 python in _console: renpy.config.stdout_callbacks.append(console.stdout_line) renpy.config.stderr_callbacks.append(console.stderr_line) +label console: + + show screen console + $ renpy.game.context().force_checkpoint = True + $ renpy.exports.checkpoint(hard="not_greedy") + $ ui.interact() + return + init python in _console: import pygame import re @@ -344,8 +373,15 @@ init python in _console: console.start() - renpy.show_screen("console") - renpy.restart_interaction() + if renpy.game.context().rollback: + try: + renpy.rollback(checkpoints=0, force=True, greedy=False, current_label="console") + except renpy.game.CONTROL_EXCEPTIONS: + raise + except Exception: + pass + + renpy.call_in_new_context("console") map_event = renpy.display.behavior.map_event @@ -603,7 +639,13 @@ screen console: hbox: yfill False - textbutton "Modal: [is_modal]" action ToggleScreenVariable("is_modal", True, False) + spacing 10 + + if is_modal: + textbutton "Modal: [is_modal]" action [ToggleScreenVariable("is_modal", True, False), Return()] + else: + textbutton "Modal: [is_modal]" action [ToggleScreenVariable("is_modal", True, False), Hide("console"), _console.enter] + textbutton "Include STDOUT: [include_stdout]" action ToggleScreenVariable("include_stdout", True, False) text "Ren'py Scripting: [scripting]" @@ -653,7 +695,11 @@ screen console: text "Command:" add consoleinput - key "console_exit" action Hide("console") + if is_modal: + key "console_exit" action [Hide("console"), Return()] + else: + key "console_exit" action Hide("console") + key "console_older" action _console.console.older key "console_newer" action _console.console.newer