Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions inkcpp/runner_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,12 @@ void runner_impl::start_frame(uint32_t target)
}
_evaluation_mode = false; // unset eval mode when enter function or tunnel

// Do we visit the knot? In Ink, all visits count for e.g. knot tags.
const bool track_knot_visit = type == frame_type::function;

// Do the jump
inkAssert(_story->instructions() + target < _story->end(), "Diverting past end of story data!");
jump(_story->instructions() + target, true, false);
jump(_story->instructions() + target, true, track_knot_visit);
}

frame_type runner_impl::execute_return()
Expand Down Expand Up @@ -461,13 +464,16 @@ frame_type runner_impl::execute_return()
}
}

// Do we visit the knot? In Ink, all visits count for e.g. knot tags. Since we tracked the visit
// when entering the thread or tunnel, we need to track the return to where we came from.
const bool track_knot_visit = type == frame_type::function;

// Jump to the old offset
inkAssert(
_story->instructions() + offset < _story->end(),
"Callstack return is outside bounds of story!"
);
jump(_story->instructions() + offset, false, false);
jump(_story->instructions() + offset, false, track_knot_visit);

// Return frame type
return type;
Expand Down
1 change: 1 addition & 0 deletions inkcpp_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ add_executable(
Globals.cpp
Lists.cpp
Tags.cpp
TagsAndBranching.cpp
NewLines.cpp
FallbackFunction.cpp
LabelCondition.cpp
Expand Down
97 changes: 97 additions & 0 deletions inkcpp_test/TagsAndBranching.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include "catch.hpp"
#include "system.h"

#include <../runner_impl.h>
#include <choice.h>
#include <compiler.h>
#include <globals.h>
#include <runner.h>
#include <story.h>

using namespace ink::runtime;

SCENARIO("TagsAndBranching", "[tags][branching]")
{
GIVEN("A story with tags and branching")
{
story* _ink = story::from_file(INK_TEST_RESOURCE_DIR "TagsAndBranching.bin");
runner _thread = _ink->new_runner();

WHEN("Starting the thread")
{
CHECK_FALSE(_thread->has_tags());
CHECK_FALSE(_thread->has_knot_tags());
CHECK(_thread->get_current_knot() == 0);
}

WHEN("On the plain text line")
{
CHECK(_thread->getline() == "Plain text\n");
THEN("It has tags")
{
CHECK(! _thread->has_knot_tags());
CHECK(_thread->has_tags());
REQUIRE(_thread->num_tags() == 1);
REQUIRE(std::string(_thread->get_tag(0)) == "plain_text_tag");
}
}

WHEN("In the knot")
{
// Skip previous test
_thread->getline();
CHECK(_thread->getline() == "Knot text\n");
THEN("It has tags")
{
CHECK(_thread->get_current_knot() == ink::hash_string("Knot"));
CHECK(_thread->has_knot_tags());
REQUIRE(_thread->num_knot_tags() == 1);
REQUIRE(std::string(_thread->get_knot_tag(0)) == "knot_tag");
CHECK(_thread->has_tags());
REQUIRE(_thread->num_tags() == 2);
REQUIRE(std::string(_thread->get_tag(0)) == "knot_tag");
REQUIRE(std::string(_thread->get_tag(1)) == "knot_text_tag");
}
}

WHEN("In the tunnel")
{
// Skip previous tests
_thread->getline();
_thread->getline();
CHECK(_thread->getline() == "Tunnel text\n");
THEN("It has tags")
{
// This doesn't pass yet, not sure why.
// CHECK(_thread->get_current_knot() == ink::hash_string("Tunnel"));
CHECK(_thread->has_knot_tags());
REQUIRE(_thread->num_knot_tags() == 1);
REQUIRE(std::string(_thread->get_knot_tag(0)) == "tunnel_tag");
CHECK(_thread->has_tags());
REQUIRE(_thread->num_tags() == 2);
REQUIRE(std::string(_thread->get_tag(0)) == "tunnel_tag");
REQUIRE(std::string(_thread->get_tag(1)) == "tunnel_text_tag");
}
}

WHEN("In the thread")
{
// Skip previous tests
_thread->getline();
_thread->getline();
_thread->getline();
CHECK(_thread->getline() == "Thread text\n");
THEN("It has tags")
{
CHECK(_thread->get_current_knot() == ink::hash_string("Thread"));
CHECK(_thread->has_knot_tags());
REQUIRE(_thread->num_knot_tags() == 1);
REQUIRE(std::string(_thread->get_knot_tag(0)) == "thread_tag");
CHECK(_thread->has_tags());
REQUIRE(_thread->num_tags() == 2);
REQUIRE(std::string(_thread->get_tag(0)) == "thread_tag");
REQUIRE(std::string(_thread->get_tag(1)) == "thread_text_tag");
}
}
}
}
23 changes: 23 additions & 0 deletions inkcpp_test/ink/TagsAndBranching.ink
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Plain text # plain_text_tag
->Knot

=== Continue
->Tunnel->
<-Thread
->DONE

// All these knots should be tracked for tagging and visit counts
=== Knot
#knot_tag
Knot text #knot_text_tag
->Continue

=== Tunnel
#tunnel_tag
Tunnel text #tunnel_text_tag
->->

=== Thread
#thread_tag
Thread text #thread_text_tag
->DONE
Loading