From d8e03c6edf8643af8775828e9cc175c2c9fefd21 Mon Sep 17 00:00:00 2001 From: willvale <66674079+willvale@users.noreply.github.com> Date: Sun, 5 Jul 2026 23:49:48 +1200 Subject: [PATCH] Add support for jumping without resetting the callstack, after the C# runtime. Useful for things like restarting the current knot. --- inkcpp/include/runner.h | 11 +++++++++-- inkcpp/runner_impl.cpp | 12 ++++++++---- inkcpp/runner_impl.h | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/inkcpp/include/runner.h b/inkcpp/include/runner.h index 750c3227..34abf08f 100644 --- a/inkcpp/include/runner.h +++ b/inkcpp/include/runner.h @@ -62,9 +62,13 @@ class runner_interface * to the content at the specified path. * * @param path path to search and move execution to + * @param reset_callstack If true, discard the call stack when moving. + * This is the default, safe, behaviour. Otherwise retain the current + * stack as far as possible. + * * @return If the path was found */ - virtual bool move_to(hash_t path) = 0; + virtual bool move_to(hash_t path, bool reset_callstack = true) = 0; /** * Moves the runner to the specified path. @@ -73,9 +77,12 @@ class runner_interface * to the content at the specified path. * * @param path path to search and move execution to + * @param reset_callstack If true, discard the call stack when moving. + * This is the default, safe, behaviour. Otherwise retain the current + * stack as far as possible. * @return If the path was found */ - bool move_to(const char* path) { return move_to(ink::hash_string(path)); } + bool move_to(const char* path, bool reset_callstack = true) { return move_to(ink::hash_string(path), reset_callstack); } /** * Can the runner continue? diff --git a/inkcpp/runner_impl.cpp b/inkcpp/runner_impl.cpp index c987311a..1b07926e 100644 --- a/inkcpp/runner_impl.cpp +++ b/inkcpp/runner_impl.cpp @@ -823,7 +823,7 @@ const char* runner_impl::getline_alloc() return res; } -bool runner_impl::move_to(hash_t path) +bool runner_impl::move_to(hash_t path, bool reset_callstack) { // find the path ip_t destination = _story->find_offset_for(path); @@ -832,9 +832,13 @@ bool runner_impl::move_to(hash_t path) return false; } - // Clear state and move to destination - reset(); - _ptr = _story->instructions(); + // Clear state if requested, + if (reset_callstack) { + reset(); + _ptr = _story->instructions(); + } + + // Don't track visit (are we sure this is right?) const bool record_visits = false; const bool track_knot_visit = false; jump(destination, record_visits, track_knot_visit); diff --git a/inkcpp/runner_impl.h b/inkcpp/runner_impl.h index 04660116..4c0f9f09 100644 --- a/inkcpp/runner_impl.h +++ b/inkcpp/runner_impl.h @@ -129,7 +129,7 @@ class runner_impl virtual const char* getline_alloc() override; // move to path - virtual bool move_to(hash_t path) override; + virtual bool move_to(hash_t path, bool reset_callstack = true) override; // move to path but keep as much state as possible bool migrate_to(const loader& loader, hash_t path);