Skip to content

Commit 7376829

Browse files
committed
Fix typo in tracking selection
Track non-functions on jump, don't update counts on return. Also: * Remove parameter from visit() which makes it do nothing, just don't call it. * Add named Booleans for everywhere we call jump - 3 parameters of the same type with default values is easy to get wrong otherwise. In future we should change this to a set of flags, but I want to see if the logic can be cleaned up a bit first. It's fiddly.
1 parent b12e0f6 commit 7376829

4 files changed

Lines changed: 47 additions & 29 deletions

File tree

inkcpp/globals_impl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@ globals_impl::globals_impl(const story_impl* story)
3030
}
3131
}
3232

33-
void globals_impl::visit(uint32_t container_id, bool preserve_turns)
33+
void globals_impl::visit(uint32_t container_id)
3434
{
35-
const int32_t existing_turns = _visit_counts[container_id].turns;
3635
_visit_counts.set(
37-
container_id, {_visit_counts[container_id].visits + (preserve_turns ? 0 : 1),
38-
preserve_turns ? existing_turns : 0}
36+
container_id, {_visit_counts[container_id].visits + 1, 0}
3937
);
4038
}
4139

inkcpp/globals_impl.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ class globals_impl final
6565

6666
public:
6767
// Records a visit to a container.
68-
// If preserve_turns is true the existing turns-since counter is kept intact
69-
// (used during snapshot migration to avoid clobbering the restored value).
70-
void visit(uint32_t container_id, bool preserve_turns = false);
68+
void visit(uint32_t container_id);
7169

7270
// Checks the number of visits to a container
7371
uint32_t visits(uint32_t container_id) const;

inkcpp/runner_impl.cpp

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

436439
frame_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;

inkcpp_test/TagsAndBranching.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ SCENARIO("TagsAndBranching", "[tags][branching]")
6262
CHECK(_thread->getline() == "Tunnel text\n");
6363
THEN("It has tags")
6464
{
65-
// This doesn't pass yet, not sure why.
66-
// CHECK(_thread->get_current_knot() == ink::hash_string("Tunnel"));
6765
CHECK(_thread->has_knot_tags());
6866
REQUIRE(_thread->num_knot_tags() == 1);
6967
REQUIRE(std::string(_thread->get_knot_tag(0)) == "tunnel_tag");
@@ -83,7 +81,6 @@ SCENARIO("TagsAndBranching", "[tags][branching]")
8381
CHECK(_thread->getline() == "Thread text\n");
8482
THEN("It has tags")
8583
{
86-
CHECK(_thread->get_current_knot() == ink::hash_string("Thread"));
8784
CHECK(_thread->has_knot_tags());
8885
REQUIRE(_thread->num_knot_tags() == 1);
8986
REQUIRE(std::string(_thread->get_knot_tag(0)) == "thread_tag");

0 commit comments

Comments
 (0)