@@ -354,8 +354,8 @@ void runner_impl::jump(ip_t dest, bool record_visits, bool track_knot_visit, boo
354354 const container_data_t & dest_container = _story->container_data (dest_id);
355355 if (dest_offset == dest_container._start_offset ) {
356356 // Record direct jump to non-knot if requested. (Knots handled below.)
357- if (record_visits && ! dest_container.knot ()) {
358- _globals->visit (dest_id, preserve_turns );
357+ if (! preserve_turns && record_visits && ! dest_container.knot ()) {
358+ _globals->visit (dest_id);
359359 }
360360
361361 // Consume instruction so we don't process it again during normal flow. (We need to do this here
@@ -387,8 +387,8 @@ void runner_impl::jump(ip_t dest, bool record_visits, bool track_knot_visit, boo
387387 //
388388 // Ink has a rule about incrementing visit counts when you jump to the top of a knot, which
389389 // seems to need to override inkcpp's knot_visit flag.
390- if (track_knot_visit || container._start_offset == dest_offset) {
391- _globals->visit (id, preserve_turns );
390+ if (! preserve_turns && ( track_knot_visit || container._start_offset == dest_offset) ) {
391+ _globals->visit (id);
392392 }
393393
394394 // If tracking, update with the first knot we encounter, which is the one closest to the top
@@ -425,12 +425,15 @@ void runner_impl::start_frame(uint32_t target)
425425 }
426426 _evaluation_mode = false ; // unset eval mode when enter function or tunnel
427427
428- // Do we visit the knot? In Ink, all visits count for e.g. knot tags.
429- const bool track_knot_visit = type == frame_type::function;
428+ // Always record visits
429+ const bool record_visits = true ;
430+
431+ // Do we visit the knot? We need to visit anything that can have knot tags.
432+ const bool track_knot_visit = type != frame_type::function;
430433
431434 // Do the jump
432435 inkAssert (_story->instructions () + target < _story->end (), " Diverting past end of story data!" );
433- jump (_story->instructions () + target, true , track_knot_visit);
436+ jump (_story->instructions () + target, record_visits , track_knot_visit);
434437}
435438
436439frame_type runner_impl::execute_return ()
@@ -464,16 +467,21 @@ frame_type runner_impl::execute_return()
464467 }
465468 }
466469
467- // Do we visit the knot? In Ink, all visits count for e.g. knot tags. Since we tracked the visit
468- // when entering the thread or tunnel, we need to track the return to where we came from.
469- const bool track_knot_visit = type == frame_type::function;
470+ // Never record visits
471+ const bool record_visits = false ;
472+
473+ // Do we visit the knot? This needs to match what we tracked in start_frame.
474+ const bool track_knot_visit = type != frame_type::function;
475+
476+ // Returns should never update visit counts.
477+ const bool preserve_turns = true ;
470478
471479 // Jump to the old offset
472480 inkAssert (
473481 _story->instructions () + offset < _story->end (),
474482 " Callstack return is outside bounds of story!"
475483 );
476- jump (_story->instructions () + offset, false , track_knot_visit);
484+ jump (_story->instructions () + offset, record_visits , track_knot_visit, preserve_turns );
477485
478486 // Return frame type
479487 return type;
@@ -631,7 +639,11 @@ void runner_impl::choose(size_t index)
631639 inkAssert (prev != nullptr , " No 'done' point recorded before finishing choice output" );
632640
633641 // Move to the previous pointer so we track our movements correctly
634- jump (prev, false , false );
642+ {
643+ const bool record_visits = false ;
644+ const bool track_knot_visit = false ;
645+ jump (prev, record_visits, track_knot_visit);
646+ }
635647 _done = nullptr ;
636648
637649 // Collapse callstacks to the correct thread
@@ -641,7 +653,9 @@ void runner_impl::choose(size_t index)
641653 _eval.clear ();
642654
643655 // Jump to destination and clear choice list
644- jump (_story->instructions () + c.path (), true , false );
656+ const bool record_visits = true ;
657+ const bool track_knot_visit = false ;
658+ jump (_story->instructions () + c.path (), record_visits, track_knot_visit);
645659 clear_choices ();
646660 _entered_knot = false ;
647661}
@@ -821,7 +835,9 @@ bool runner_impl::move_to(hash_t path)
821835 // Clear state and move to destination
822836 reset ();
823837 _ptr = _story->instructions ();
824- jump (destination, false , false );
838+ const bool record_visits = false ;
839+ const bool track_knot_visit = false ;
840+ jump (destination, record_visits, track_knot_visit);
825841
826842 return true ;
827843}
@@ -852,7 +868,9 @@ bool runner_impl::migrate_to(const loader& loader, hash_t path)
852868 while (read<Command>(eval_start) != Command::START_EVAL ) {
853869 eval_start -= 6 ;
854870 }
855- jump (eval_start, false , false );
871+ const bool record_visits = false ;
872+ const bool track_knot_visit = false ;
873+ jump (eval_start, record_visits, track_knot_visit);
856874 while (_ptr != iter + 6 ) {
857875 step ();
858876 }
@@ -866,7 +884,10 @@ bool runner_impl::migrate_to(const loader& loader, hash_t path)
866884 // without this the visit() call inside jump() would reset them to 0.
867885 _container.clear ();
868886 _ptr = nullptr ;
869- jump (destination, false , true , true );
887+ const bool record_visits = false ;
888+ const bool track_knot_visit = false ;
889+ const bool preserve_turns = true ;
890+ jump (destination, record_visits, track_knot_visit, preserve_turns);
870891
871892 if (loader.old_ref_table
872893 && ! _globals->lists ().migrate_variables (
@@ -1208,7 +1229,9 @@ void runner_impl::step()
12081229 inkAssert (
12091230 _story->instructions () + target < _story->end (), " Diverting past end of story data!"
12101231 );
1211- jump (_story->instructions () + target, true , ! (flag & CommandFlag::DIVERT_HAS_CONDITION ));
1232+ const bool record_visits = true ;
1233+ const bool track_knot_visit = ! (flag & CommandFlag::DIVERT_HAS_CONDITION );
1234+ jump (_story->instructions () + target, record_visits, track_knot_visit);
12121235 } break ;
12131236 case Command::DIVERT_TO_VARIABLE : {
12141237 // Get variable value
@@ -1230,9 +1253,11 @@ void runner_impl::step()
12301253 inkAssert (val, " Jump destiniation needs to be defined!" );
12311254
12321255 // Move to location
1256+ const bool record_visits = true ;
1257+ const bool track_knot_visit = ! (flag & CommandFlag::DIVERT_HAS_CONDITION );
12331258 jump (
1234- _story->instructions () + val->get <value_type::divert>(), true ,
1235- ! (flag & CommandFlag:: DIVERT_HAS_CONDITION )
1259+ _story->instructions () + val->get <value_type::divert>(),
1260+ record_visits, track_knot_visit
12361261 );
12371262 inkAssert (_ptr < _story->end (), " Diverted past end of story data!" );
12381263 } break ;
0 commit comments